Terraform : remote state configuration DRY avec Terragrunt
Terraform : remote state configuration DRY avec Terragrunt
1) Introduction de notre sujet
Terraform stocke l'image de l'infrastructure déployée dans un fichier nommé terraform.tfstate, avec un format json. Ce fichier est stocké :- par défaut dans chaque répertoire contenant un groupe de ressources ou modules à déployer. Nous avons donc un fichier terraform.tfstate à l'intérieur de chaque répertoire. Cette solution présente l'inconvénient d'un travail collaboratif difficile ainsi que la question de la sauvegarde de ces fichiers. Le backend est dit "local".
├── ec2-site1 │ ├── ec2-site1.auto.tfvars │ ├── main.tf │ ├── terraform.tfstate │ └── var.tf │ ├── ec2-site2 │ ├── ec2-site2.auto.tfvars │ ├── main.tf │ ├── terraform.tfstate │ └── var.tf
- Dans un lieu de stockage mutualisé et sauvegardé, avec éventuellement l'existence d'un versionning. Nous utiliserons ici la solution de backend S3 sur AWS. Cette solution permet un travail collaboratif sur les fichiers terraform.tfstate avec l’utilisation conjointe d'une table DynamoDB pour gérer les accès concurrents. Les fichiers terraform.tfstate ne sont plus stockés localement.
├── ec2-site1 │ ├── ec2-site1.auto.tfvars │ ├── main.tf │ └── var.tf │ ├── ec2-site2 │ ├── ec2-site2.auto.tfvars │ ├── main.tf │ └── var.tfmais sont contenus dans un repo S3 :
$ aws s3 ls jpc-terraform-repo/us-west-2 --recursive 2020-07-14 19:38:23 0 us-west-2/ 2020-07-25 11:18:50 157 us-west-2/projetx/ec2-site1/terraform.tfstate 2020-07-25 11:18:50 157 us-west-2/projetx/ec2-site2/terraform.tfstatePour utiliser un backend S3, il faut positionner dans un fichier du répertoire des ressources à créer le code suivant :
terraform {
backend "s3" {
bucket = "jpc-terraform-repo"
key = "path/to/my/key"
region = "us-west-2"
}
}
"Don't Repeat Yourself."Partant au contraire de ce principe, un wrapper pour Terraform, en l'occurence Terragrunt, va nous permettre de palier cet inconvénient et appliquer le précepte "DRY" au remote backend notamment. Cf. https://terragrunt.gruntwork.io/docs/features/keep-your-remote-state-configuration-dry
2) Mise en place du paramétrage remote backend DRY avec Terragrunt
La mise en place de Terragrunt pour l'automatisation des remote backends repose sur la création de fichiers terragrunt.hcl :- Au plus bas de l’arborescence du projet. Dans ce fichier global est défini le paramétrage des backends, avec principalement le champ "key" sous forme de variable :
remote_state { backend = "s3" config = { bucket = "jpc-terraform-repo" key = "us-west-2/${path_relative_to_include()}/terraform.tfstate" region = "us-west-2" encrypt = false dynamodb_table = "jpc-terraform-lock" } }
- Dans chacun des autres sous-répertoires, un fichier terragrunt.hcl contenant la valeur générique :
include { path = find_in_parent_folders() }L'arborescence des répertoires du projet correspondra à celle-ci :
├── projetx │ │ │ ├── ec2-site1 │ │ ├── ec2-site1.auto.tfvars │ │ ├── main.tf │ │ ├── terragrunt.hcl <======== FICHIER GENERIQUE │ │ └── var.tf │ │ │ ├── ec2-site2 │ │ ├── ec2-site2.auto.tfvars │ │ ├── main.tf │ │ ├── terragrunt.hcl <======== FICHIER GENERIQUE │ │ └── var.tf │ │ ├── terragrunt.hcl <====== FICHIER GLOBAL
3) Déploiement
Terragrunt nécessite l'installation préalable de Terraform car c'est seulement un wrapper de Terraform. Il s'installe de la même manière que Terraform, par téléchargement d'un binaire. Il suffit de lancer la commande "terragrunt init" à la place de la commande "terraform init" pour que le fichier de backendS3 soit créé avec une clé générée automatiquement, correspondant au pattern défini dans le fichier terragrunt.hcl global.$ aws s3 ls jpc-terraform-repo/us-west-2 --recursive 2020-07-14 19:38:23 0 us-west-2/ 2020-07-25 11:18:50 157 us-west-2/projetx/ec2-site1/terraform.tfstate 2020-07-25 11:18:50 157 us-west-2/projetx/ec2-site2/terraform.tfstateEn fait, Terragrunt surcouche Terraform en paramétrant le backend sur la ligne de commande Terraform :
# terragrunt init terraform init -backend-config=bucket=jpc-terraform-repo -backend-config=dynamodb_table=jpc-terraform-lock -backend-config=encrypt=false -backend-config=key=us-west-2/projetx/ec2/terraform.tfstate -backend-config=region=us-west-2Une fois le backend S3 initié grâce à la commande "terragrunt init", les commandes, dans ce cas de figure d’utilisation de Terragrunt, peuvent être indifféremment "Terragrunt nom_commande_terraform" ou "Terraform nom_commande_terraform". La commande "terragrunt init" ayant configuré le fichier ./.terraform/terraform.tfstate avec les caractéristiques du backend S3.
4) Lancement de commandes multiples
Une fois le paramétrage ci-dessus initié, il est possible aussi de lancer des commandes qui exécuteront de manière concurrente ou gérée par des liens de dépendance les répertoires des différents répertoires du projet. Les commandes seront :terragrunt apply-all, terragrunt destroy-all, terragrunt output-all, terragrunt plan-all.
Il n'y a pas par contre de commande terragrunt init.