Comment migrer l’état Terraform vers GitLab CI/CD

En tant que professionnel du logiciel travaillant avec Infrastructure as Code (IaC), il est probable que vous utilisiez beaucoup 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 que vous rencontrez. En gros, l’état Terraform contient des informations sensibles, qui ne devraient pas être stockées par contrôle de version, mais, en même temps, ne sera pas évolutif si vous avez plusieurs utilisateurs travaillant sur le même état Terraform. La solution à cela ? Les backends.

Il est important de noter que vous pourriez stocker ce fichier d’état sur un bucket S3 et utiliser DynamoDB pour gérer l’état de verrouillage. Cependant, cette approche vous forcerait à 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 pour l’intégration de Terraform en fournissant un moyen de stocker et de gérer l’état Terraform, ainsi qu’un moyen facile 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 comment mettre en place 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 pour que GitLab gère l’état Terraform
  • Comment faire pour que GitLab exécute votre IaC via un pipeline CI
    • Astuce bonus : Infracost
  • Conclusion

Qu’est-ce que l’état Terraform ?

Terraform enregistre toute information concernant l’infrastructure définie dans votre code via un fichier d’état. Écrit en JSON, il enregistre essentiellement une correspondance entre le code Terraform et les ressources réelles créées. Voici un exemple de ce à quoi pourrait ressembler un terraform.tfstate. Principalement, chaque fois que vous exécutez Terraform, il récupère le statut le plus récent pour son instance EC2 et le compare avec votre configuration Terraform pour déterminer quelles modifications doivent être appliquées :

 

{   
     "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, ce terraform.tfstate est stocké localement où vous avez vos fichiers Terraform, planifiez et appliquez vos modifications. Pour un projet personnel où vous effectuez simplement des tests, c’est acceptable, mais ce n’est 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 devez travailler avec un autre ingénieur, les choses pourraient devenir compliquées. Vous devrez tous les deux vous assurer d’utiliser la dernière version de l’état et vous pourriez être confronté à des conditions de course si vous exécutez un plan Terraform ou appliquez en même temps.
  • Protéger 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 clair est une mauvaise idée.
  • Verrouillage: La plupart des systèmes de contrôle de version ne prennent pas 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 un fichier d’état géré par le contrôle de source.

Comment faire pour que GitLab gère l’état Terraform

Étant donné que Terraform est considéré comme la norme en matière de provisionnement d’infrastructure cloud, GitLab propose depuis un an environ un moyen de stocker et gérer l’état Terraform. Pour cette raison, nous avons souhaité partager avec vous le processus de migration, car nous avons récemment commencé à utiliser GitLab pour gérer notre infrastructure en code (IaC).

Pour cet article, nous supposons que vous utilisez un état local et que votre état est géré avec un bucket AWS S3 ou une autre solution de backend.

Tout d’abord, vous devrez modifier votre backend.tf pour utiliser HTTP:

 

terraform {  
    backend "http" {} 
  }

Ensuite, vous devrez configurer quatre variables dans votre terminal:

1. PROJECT_ID : Vous pouvez trouver cela facilement en naviguant sur votre repo sur la page  » Vue d’ensemble du projet « .

2. TF_USERNAME : Le nom d’utilisateur GitLab qui a accès au repo sur lequel vous travaillez.

3. TF_PASSWORD : Le jeton d’accès généré à partir de votre compte GitLab.

4. TF_ADDRESS : URL du backend d’é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 sa précédente localisation 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  » pour que GitLab puisse commencer à gérer votre fichier d’état. Voici un exemple de l’état local vers GitLab:


Exemple de S3 vers GitLab:

Now, you can navigate to Infrastructure > Terraform from the GitLab interface and see your state:

I noticed for some of the state files I had from S3 will be blank even after using the migrate-state command ran previously. In this case, you can run this:  

 
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 pour votre fichier d’état Terraform, mais la visualisation/restauration des versions antérieures via l’interface Web nécessite d’utiliser un plan Premium de GitLab. Sinon, vous devrez effectuer une requête API GraphQL requête.

Comment faire en sorte que GitLab exécute votre IaC via un pipeline CI

GitLab fournit une image Docker qui contient GitLab-Terraform, qui est un script enveloppe léger autour de la binaire Terraform officielle. Vous pouvez également utiliser l’image Docker officielle de Hashicorp. Vous trouverez plus d’informations sur l’image GitLab Terraform ici.

Une fois que le job Terraform apply s’exécute, vous pourrez voir quand l’état a été utilisé et avec quel pipeline.

Learn more about what our gitlab-ci.yml looks like here. Below, are the variables that will need to be defined on the project level.

Astuce bonus : Infracost

Comme vous avez pu le remarquer, 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 donne une estimation des coûts chaque fois que vous définissez un nouveau ressource à votre IaC.

Conclusion

Avoir votre état Terraform et votre CI en cours d’exécution sur Gitlab est une excellente façon de suivre les meilleures pratiques GitOps. Ils forment une excellente combinaison pour développer et déployer IaC. Puisque la plupart d’entre vous utilisent probablement déjà GitLab pour vos dépôts, 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 versioning, le verrouillage et le déverrouillage de l’état.

Source:
https://dzone.com/articles/how-to-migrate-terraform-state-to-gitlab-cicd