Travailler en équipe sous Terraform!

Marc Gardent
Esker-Labs
Published in
4 min readJun 28, 2019

--

Je suis membre de l’équipe Azure [aka CSA] au sein d’ESKER qui est composée de 6 membres. Nous avons mis en œuvre Terraform pour réaliser le déploiement de la solution ESKER sur un nouveau data-center Azure. Dans cet article nous allons nous interroger sur le travail en équipe avec Terraform. Commençons tout de suite par une phrase qui pourrait être énoncée trivialement par un développeur :

“Facile, tu pousses tout dans git !?”

En effet, il faut mettre le code dans un gestionnaire de sources mais il faut aussi partager le fameux tfstate pour réaliser les commandes Terraform. Au final, tout ceci n'est pas si évident dans la pratique, et voici donc les douleurs et les solutions que nous avons rencontrées les tous premiers jours en phase de prototypage.

Partager le tfstate!

Le tfstate est la base de données qui permet à Terraform de savoir s'il doit détruire, créer ou modifier les ressources.

La peine tfstate

Par défaut terraform sauve le tfstate dans le dossier de travail en local. Et donc si vous travaillez chacun dans votre coin, il y aura autant de tfstate que de développeurs. Et il n'y a aucun moyen de les fusionner plus tard ! Il n'est donc vraiment pas possible de travailler en équipe de cette façon.

S'ajoute que le tfstate doit être soigné comme la prunelle de ses yeux ! Le perdre vous obligerait à retrouver tous les ID des ressources et les faire correspondre avec les ID de Terraform, ce qui représente une énorme dose de boulot !

TERRAFORM a tout prévu !

Pour partager le tfstate efficacement, il faut déclarer un lieu de stockage centralisé disponible pour tous appelé backend. Les commandes Terraform verrouillent l'accès au tfstate et permettent donc de travailler sereinement en équipe ! Par exemple, nous utilisons les StorageAccount, Azure étant aussi notre provider de ressources. Le choix du backend n'est pas vraiment une difficulté, et il se fait en fonction de votre environnement. Il faut juste savoir que terraform supporte quelques backends incompatibles avec la fonctionnalité de lock. Pour revenir à Azure, voici un exemple de déclaration :

terraform {
backend "azurerm" {
storage_account_name = "mystorageAccount"
container_name = "myContainer"
key = "myState.tfstate"
}
}

Pensez donc à faire un système de backup, ainsi qu’à la sécurité : il y a certains de vos secrets dans ce fichier !

Et le Code ?

Nous pourrions dire :

“Facile, tu pousses tout dans git!?”

Presque mais non ! Encore une fois le tfstate fait parler de lui !

Les problèmes commencent

Si vous réalisez un seul workspace - autrement dit l'ensemble de vos fichiers .tf dans un même dossier, votre tfstate va être de plus en plus gros et finir par ralentir les commandes de plan et apply ! S'ajoute que faire des opérations de maintenance du tfstate (renommer, importer des ressources...) avec une personne qui en parallèle veut pousser sa modification provoque des blocages non souhaitables. Et on ne parle que du cas favorable dans lequel les gens se parlent ! Bref, pas terrible !

Diviser pour régner

Notre conclusion est qu’il faut découper en plusieurs workspaces - sous entendu avoir plusieurs bases de code et donc autant de tfstate. Nous avons fait le choix de découper fonctionnellement des workspaces par rôle : persistance, frontend, backend... Le tout est complété par un workspace technique transverse pour le réseau.

Reste à savoir comment stocker tout ceci et donc enfin parler de repository , sous entendu git, mercurial et compagnie ! La documentation Terraform Entreprise fait plusieurs propositions - elle en parle, parlons-en :

1. Un seul repository et un dossier par workspace :

  • PRO, je clone un seul repo sur ma machine
  • CON, la plateforme d’intégration et livraison continue aka CI/CD empile les plan pour l'ensemble des workspaces, à chaque commit ! L'enfer c'est l'autre

2. Un seul repository mais une branche par workspace :

  • PRO, je clone un seul repository sur ma machine
  • CON, la maintenance du code sur plusieurs workspaces devient une vraie peine

3. Un repository par workspace :

  • PRO, la CI/CD devient plus lisible, chaque workspace a son propre cycle de vie
  • CON, devoir cloner plusieurs repositories pour travailler en local

Nous avons expérimenté les deux premières en phase de prototypage. Et nous en sommes actuellement à un repository par workspace pour une meilleure intégration à la CI/CD. Pour compenser la peine, nous avons mis en place un script pour initier tous les repositories pour les machines de développement.

En découpant le code, vous pourriez avoir besoin d'informations qui sont publiées dans un autre tfstate. Vous pouvez utiliser la ressource remote_state par exemple :

# Déclaration data "terraform_remote_state" "my_state" {
backend = "azurerm"
config {
storage_account_name = "mystorageAccount"
container_name = "myContainer"
key = "myState.tfstate"
}
}
# Utilisation locals {
subnet_id= "data.terraform_remote_state.my_state.my_subnet_id"
}

Et maintenant

Vous pensez que c’est joué ? Et bien pas du tout ! A ce stade, le développeur aura des surprises dans le plan avec des ressources ajoutées dans le dernier commit non récupérées sur sa machine ! Sans compter que pour lancer les commandes très vite, il vous faudra maintenir un fichier de configuration appelé tfvars . Donc à cette étape c'est vivable mais il faut parler entres collègues :).

Ceci rappelle la vie sans les plateformes de CI/CD et renforce leur légitimité.

En effet, je vous propose d’utiliser une plateforme de CI/CD pour résoudre tout ceci. Vous pouvez regarder du côté de Terraform Entreprise qui propose une solution clef en main. Nous avons choisi la plateforme de CI/CD AzureDevOps et je vous expliquerai pourquoi et comment dans un futur article !

A retrouver dans la documentation officielle terraform, les notions évoquées :

--

--

Marc Gardent
Esker-Labs

IT Consultant, and Indie Creator: join @ludopant on Instagram: video games, board games, graphics, artworks, comics, animations.