Terragrunt
Terragrunt est un wrapper Terraform open-source créé par Gruntwork. Il résout les problèmes de répétition (DRY) dans les projets multi-environnements et multi-régions, sans modifier le code HCL Terraform. C'est l'outil de référence dès qu'un projet dépasse 3 environnements.
Le problème que résout Terragrunt
Sans Terragrunt, une infrastructure avec 3 environnements (dev, staging, prod) dans 2 régions nécessite 6 copies du même bloc backend, 6 copies de la configuration provider, 6 ensembles de fichiers quasi-identiques. Toute modification doit être répercutée 6 fois.
Terragrunt centralise ces configurations répétées dans un fichier terragrunt.hcl racine et les hérite dans chaque environnement.
Structure d'un projet Terragrunt
infrastructure/
├── terragrunt.hcl # config racine partagée
├── modules/
│ ├── vpc/
│ └── ec2/
└── live/
├── eu-west-1/
│ ├── prod/
│ │ ├── vpc/
│ │ │ └── terragrunt.hcl
│ │ └── ec2/
│ │ └── terragrunt.hcl
│ └── staging/
│ └── vpc/
│ └── terragrunt.hcl
└── us-east-1/
└── prod/
└── vpc/
└── terragrunt.hclterragrunt.hcl racine
# infrastructure/terragrunt.hcl
locals {
region = basename(dirname(path_relative_to_include()))
environment = basename(dirname(path_relative_to_include()))
account_id = get_aws_account_id()
}
remote_state {
backend = "s3"
generate = {
path = "backend.tf"
if_exists = "overwrite_terragrunt"
}
config = {
bucket = "tfstate-${local.account_id}-${local.region}"
key = "${path_relative_to_include()}/terraform.tfstate"
region = local.region
encrypt = true
dynamodb_table = "terraform-locks"
}
}
generate "provider" {
path = "provider.tf"
if_exists = "overwrite_terragrunt"
contents = <terragrunt.hcl par module
# live/eu-west-1/prod/vpc/terragrunt.hcl
include "root" {
path = find_in_parent_folders()
}
terraform {
source = "../../../../modules/vpc"
}
inputs = {
name = "prod-vpc"
cidr_block = "10.0.0.0/16"
environment = "prod"
}Dépendances entre modules
# live/eu-west-1/prod/ec2/terragrunt.hcl
include "root" {
path = find_in_parent_folders()
}
dependency "vpc" {
config_path = "../vpc"
mock_outputs = {
vpc_id = "vpc-00000000"
public_subnet_ids = ["subnet-00000000"]
}
}
terraform {
source = "../../../../modules/ec2"
}
inputs = {
vpc_id = dependency.vpc.outputs.vpc_id
subnet_id = dependency.vpc.outputs.public_subnet_ids[0]
}Commandes Terragrunt
# Équivalents des commandes Terraform
terragrunt init
terragrunt plan
terragrunt apply
# Appliquer tous les modules d'un environnement en respectant les dépendances
terragrunt run-all apply --terragrunt-working-dir live/eu-west-1/prod/
# Plan de tout l'environnement
terragrunt run-all plan --terragrunt-working-dir live/eu-west-1/prod/
# Afficher le graphe de dépendances
terragrunt graph-dependencies