En tant que professionnel du logiciel gérant l’Infrastructure as Code (IaC), il y a de fortes chances que vous travailliez beaucoup avec Terraform. Lorsque vous aidez de nouveaux clients à utiliser IaC, il est courant de simplifier les choses, mais la gestion d’un fichier d’état Terraform est le premier défi auquel vous êtes confronté. Essentiellement, l’état Terraform contient des informations sensibles, qui ne doivent pas être stockées par le contrôle de source mais, en même temps, ne seront pas mises à l’échelle si plusieurs utilisateurs travaillent sur le même état Terraform. La réponse à cela? Backends.
Il est important de noter que vous pouvez stocker ce fichier d’état sur un compartiment S3 et utiliser DynamoDB pour gérer l’état de verrouillage. Cependant, cette approche vous obligera à créer des ressources supplémentaires, ce qui en fait une option compliquée, surtout si le client utilise GitLab. GitLab a récemment abaissé la barrière d’entrée à l’intégration de Terraform en fournissant un moyen de stocker et de gérer l’état de Terraform, ainsi qu’un moyen simple de configurer un CI autour de celui-ci.
Dans cet article, nous expliquerons ce qu’est un fichier d’état Terraform, comment le migrer vers GitLab et configurer un pipeline CI pour celui-ci. Vous pouvez visiter notre dépôt ici.
Table des matières
- Qu’est-ce que l’état Terraform ?
- Comment faire en sorte que GitLab gère l’état de Terraform
- Comment faire en sorte que GitLab exécute votre IaC via un pipeline CI
- Conclusion
Qu’est-ce que l’état Terraform ?
Terraform enregistre toute information sur l’infrastructure définie dans votre code via un fichier d’état. Écrit en JSON, il enregistre essentiellement un mappage du code Terraform aux ressources réelles créées. Vous trouverez ci-dessous un exemple de ce qu’est un terraform.tfstate
ressemblerait. Principalement, chaque fois que vous exécutez Terraform, il récupère le dernier état de son instance EC2 et le compare à votre configuration Terraform pour déterminer les modifications à appliquer :
{
"version": 4,
"terraform_version": "0.12.0",
"serial": 1,
"lineage": "1f2087f9-4b3c-1b66-65db-8b78faafc6fb",
"outputs": {},
"resources": [
{
"mode": "managed",
"type": "aws_instance",
"name": "example",
"provider": "provider.aws",
"instances": [
{
"schema_version": 1,
"attributes": {
"ami": "ami-0c55b159cbfafe1f0",
"availability_zone": "us-west-2a",
"id": "i-00a123a0accffffff",
"instance_state": "running",
"instance_type": "t2.micro",
"(...)": "(truncated)"
}
}
]
}
]
}
Par défaut, cela terraform.tfstate
est stocké localement où vous avez vos fichiers Terraform, planifiez et appliquez vos modifications. Pour un projet personnel où vous n’exécutez que quelques tests ; c’est bien, mais pas la méthode recommandée, voici pourquoi :
- Stocké dans un emplacement partagé: si vous hébergez ce fichier d’état sur votre poste de travail local et que vous deviez travailler avec un autre ingénieur, les choses se compliqueraient. Vous devrez tous les deux vous assurer que vous utilisez la dernière version de l’état et vous pourriez vous heurter à des conditions de concurrence si vous exécutez un plan Terraform ou postulez en même temps.
- Protégez les informations sensibles: Un fichier d’état généré peut contenir des clés de chiffrement et des mots de passe d’infrastructure. Cependant, les fichiers d’état ne sont pas chiffrés par défaut et stocker des informations sensibles en texte brut est une mauvaise idée.
- Verrouillage: La plupart des systèmes de contrôle de version ne prennent en charge aucune forme de verrouillage, ce qui empêche deux membres de l’équipe d’exécuter Terraform Apply simultanément sur le même fichier d’état. C’est une autre raison pour laquelle nous ne verrons pas de fichier d’état géré par le contrôle de code source.
Comment faire en sorte que GitLab gère l’état de Terraform
Terraform étant considéré comme la norme en matière de provisionnement d’infrastructure cloud, cela fait environ un an que GitLab a commencé à offrir un moyen de stocker et de gérer votre état Terraform. Pour cette raison, nous voulions partager le processus de migration avec vous car nous avons récemment commencé à utiliser GitLab pour gérer notre IaC.
Pour cet article, nous supposons que vous utilisez un état local et que votre état est géré avec un compartiment AWS S3 ou une autre solution backend.
Tout d’abord, vous devrez changer votre backend.tf
pour utiliser HTTP :
terraform {
backend "http" {}
}
Ensuite, vous devrez configurer quatre variables dans votre terminal :
1. PROJECT_ID
: Vous pouvez le trouver facilement en accédant à votre repo sur le « Aperçu du projet” page.
2. TF_USERNAME
: Le nom d’utilisateur Gitlab qui a accès au dépôt sur lequel vous travaillez.
3. TF_PASSWORD
: jeton d’accès généré à partir de votre utilisateur GitLab.
4. TF_ADDRESS
: URL du backend de l’état distant.
PROJECT_ID="28450092"
TF_USERNAME="florianpialoux"
TF_PASSWORD="123456789"
TF_ADDRESS="https://gitlab.com/api/v4/projects/${PROJECT_ID}/terraform/state/aws-buckets"
Vous pouvez maintenant exécuter la commande de migration qui déplacera votre état Terraform de son emplacement précédent vers GitLab avec la commande suivante :
terraform init \
-migrate-state \
-backend-config=address=${TF_ADDRESS} \
-backend-config=lock_address=${TF_ADDRESS}/lock \
-backend-config=unlock_address=${TF_ADDRESS}/lock \
-backend-config=username=${TF_USERNAME} \
-backend-config=password=${TF_PASSWORD} \
-backend-config=lock_method=POST \
-backend-config=unlock_method=DELETE \
-backend-config=retry_wait_min=5
Vous devrez fournir une confirmation par un « Oui” afin que GitLab puisse commencer à gérer votre fichier d’état. Voici un exemple d’un état local vers GitLab :
Exemple S3 vers GitLab :
Maintenant, vous pouvez naviguer vers Infrastructure > Terraform depuis l’interface GitLab et voyez votre état :

J’ai remarqué que certains des fichiers d’état que j’avais de S3 seront vides même après avoir utilisé le migrate-state
commande exécutée précédemment. Dans ce cas, vous pouvez exécuter ceci :
terraform state pull > aws-buckets.json
Copiez et collez le contenu de l’état S3 et exécutez un push :
terraform state push -lock=true aws-buckets.json
GitLab prend en charge la gestion des versions de votre fichier d’état Terraform, mais l’affichage/la restauration d’anciennes versions via l’interface utilisateur Web vous obligera à utiliser un plan GitLab Premium. Sinon, vous devrez faire une demande d’API GraphQL.
Comment obtenir GitLab pour exécuter votre IaC via un pipeline CI
GitLab fournit une image Docker qui contient GitLab-Terraform, qui est un script wrapper léger autour du binaire Terraform officiel. Vous pouvez également utiliser l’image Docker officielle de Hashicorp. Vous pouvez trouver plus d’informations sur l’image GitLab Terraform ici.
Une fois la tâche d’application Terraform exécutée, vous pourrez voir quand l’état a été utilisé et avec quel pipeline.
En savoir plus sur ce que notre gitlab-ci.yml
ressemble ici. Vous trouverez ci-dessous les variables qui devront être définies au niveau du projet.
Astuce bonus : Infracost
Comme vous l’avez peut-être remarqué, en regardant notre gitlab-ci.yaml
nous avons ajouté Infracost, qui nous permet d’avoir plus de contrôle sur notre facturation cloud car il vous donne une estimation des coûts chaque fois que vous définissez une nouvelle ressource pour votre IaC.
Conclusion
L’exécution de votre état Terraform et de votre CI sur Gitlab est un excellent moyen de suivre les meilleures pratiques GitOps. Ils forment tous deux une excellente combinaison pour développer et déployer IaC. Étant donné que la plupart d’entre vous utilisent peut-être déjà GitLab pour vos référentiels, il devient beaucoup plus simple d’avoir votre IaC sous un même toit et de laisser GitLab gérer votre état Terraform en prenant en charge le chiffrement en transit et au repos, ainsi que la gestion des versions, le verrouillage et le déverrouillage du État.