Terragrunt : scale Terraform multi-env
À la fin de ce tutoriel, vous structurerez un repo Terragrunt multi-environnements :
root.hclpartagé, units DRY (live/<env>/<region>/<unit>),generateprovider/backend,remote_stateS3 par unit,dependencyentre stacks, etterragrunt run --all— lab safe enca-central-1, sans copier-coller de roots Terraform.Niveau : Intermédiaire · Temps estimé : 55–75 min · Versions cibles : Terragrunt (release courante) · Terraform ≥ 1.9 · AWS provider ~> 5.0 · AWS CLI v2 · Dernière vérification : 2026-09-11 · Region :
ca-central-1Slug :
wow-terragrunt-scale· Série : WOW · Mot-clé SEO : terragrunt · Publish : prêt (feu vert Maître)← : Workspaces Terraform · → : State backend S3 · Multi-account org
Prérequis
- Découvrir Terraform (IaC, providers, state)
- Installer Terraform (≥ 1.9) —
terraform versionOK - Workflow init → plan → apply
- Modules : bases
- State & backend S3 + lock
- Notions workspaces (pour comprendre ce que Terragrunt remplace en scale)
- Compte AWS lab + profil SSO/
AWS_PROFILE; jamais de clés en dur - Binaire Terragrunt installé (
terragrunt --version) — terragrunt.gruntwork.io
Coût estimé : quasi 0 € si vous restez sur plan + ressources légères (SSM Parameter / S3 lab). Destroy obligatoire après apply. Region : ca-central-1.
Ce que nous allons construire
repo-iac/
├── modules/ # Terraform pur (VPC, SG, app…)
│ └── vpc/
├── live/
│ ├── root.hcl # include commun : remote_state, generate, inputs
│ ├── dev/ca-central-1/
│ │ ├── vpc/terragrunt.hcl
│ │ └── sg/terragrunt.hcl # dependency → vpc
│ └── staging/ca-central-1/
│ └── vpc/terragrunt.hcl
└── .gitignore # .terragrunt-cache, .terraform
(Schéma — alt : « Terragrunt multi-env : root.hcl, units live, remote_state S3 et dependency ».)
Étape 1 — Pourquoi Terragrunt pour scaler Terraform ?
Un root Terraform « copie-colle » par env (envs/dev, envs/prod) marche… jusqu’à 5–10 stacks. Ensuite : drift de backends, providers divergents, oubli de lock DynamoDB, et des tfvars qui se contredisent.
| Approche | Idée | Limite au scale |
|---|---|---|
| Workspaces CLI | Même code, plusieurs states | Même config ; pas multi-compte magique |
| Dossiers dupliqués | Un root par env | Copier-coller backend/provider |
| Terragrunt | Thin wrappers + modules DRY | Courbe d’apprentissage, cache .terragrunt-cache |
Terragrunt n’est pas un autre langage IaC : il génère backend/provider, compose les inputs et orchestre les units (run --all). Les modules restent du HCL Terraform standard.
Posture DEH. Labs P2 = Terraform nu. Terragrunt quand plusieurs envs × stacks rendent le DRY nécessaire.
Étape 2 — Layout live/ + root.hcl
Créez la structure (lab) :
mkdir -p modules/vpc live/dev/ca-central-1/vpc live/dev/ca-central-1/sg
mkdir -p live/staging/ca-central-1/vpc
live/root.hcl — le socle partagé (à adapter à votre bucket/table) :
# live/root.hcl
locals {
account_vars = read_terragrunt_config(find_in_parent_folders("account.hcl", "account.hcl"))
region_vars = read_terragrunt_config(find_in_parent_folders("region.hcl", "region.hcl"))
account_name = try(local.account_vars.locals.account_name, "lab")
aws_region = try(local.region_vars.locals.aws_region, "ca-central-1")
environment = try(local.account_vars.locals.environment, "dev")
}
remote_state {
backend = "s3"
generate = {
path = "backend.tf"
if_exists = "overwrite_terragrunt"
}
config = {
bucket = "deh-tfstate-${local.account_name}" # bucket lab versionné
key = "${path_relative_to_include()}/terraform.tfstate"
region = local.aws_region
encrypt = true
dynamodb_table = "deh-tf-locks" # ou mécanisme de lock documenté pour votre version
}
}
generate "provider" {
path = "provider.tf"
if_exists = "overwrite_terragrunt"
contents = <<EOF
terraform {
required_version = ">= 1.9.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = "${local.aws_region}"
default_tags {
tags = {
ManagedBy = "terragrunt"
Environment = "${local.environment}"
Project = "deh-lab"
}
}
}
EOF
}
inputs = {
aws_region = local.aws_region
environment = local.environment
}
Fichiers d’env (exemples) :
# live/dev/account.hcl
locals {
account_name = "lab"
environment = "dev"
}
# live/dev/ca-central-1/region.hcl
locals {
aws_region = "ca-central-1"
}
Chaque unit include le root :
# live/dev/ca-central-1/vpc/terragrunt.hcl
include "root" {
path = find_in_parent_folders("root.hcl")
}
terraform {
source = "../../../../../modules/vpc"
}
inputs = {
name = "deh-dev-vpc"
cidr_block = "10.20.0.0/16"
}
Le path source pointe vers un module Terraform pur (pas de Terragrunt dedans). Ajustez le nombre de ../ selon votre arborescence réelle.
Étape 3 — Module Terraform minimal (VPC lab)
Pour le lab, un module ultra-léger suffit (ou un Parameter Store si vous voulez zéro réseau) :
# modules/vpc/main.tf
variable "name" { type = string }
variable "cidr_block" { type = string }
variable "environment" { type = string }
variable "aws_region" { type = string }
resource "aws_vpc" "this" {
cidr_block = var.cidr_block
enable_dns_support = true
enable_dns_hostnames = true
tags = {
Name = var.name
Env = var.environment
}
}
output "vpc_id" {
value = aws_vpc.this.id
}
output "cidr_block" {
value = aws_vpc.this.cidr_block
}
Sécurité lab. Preférez un compte sandbox. Si VPC = trop large pour votre Free Tier / quotas, remplacez par
aws_ssm_parameteret gardez la même mécanique Terragrunt (state, dependency, run –all).
Étape 4 — dependency entre units
Le Security Group (ou une app) consomme le VPC :
# live/dev/ca-central-1/sg/terragrunt.hcl
include "root" {
path = find_in_parent_folders("root.hcl")
}
terraform {
source = "../../../../../modules/sg" # module SG minimal à créer
}
dependency "vpc" {
config_path = "../vpc"
mock_outputs = {
vpc_id = "vpc-mock-for-plan"
}
mock_outputs_allowed_terraform_commands = ["validate", "plan"]
}
inputs = {
name = "deh-dev-sg"
vpc_id = dependency.vpc.outputs.vpc_id
}
config_path: unit amont (state déjà appliqué idéalement).mock_outputs: permet unplande l’unit aval avant le premier apply du VPC.- En apply réel, Terragrunt lit les outputs du state distant de
vpc.
Ordre mental : fondations → réseau → sécurité → compute. run --all respecte les dépendances déclarées.
Étape 5 — Lab : plan / apply en ca-central-1
export AWS_PROFILE=lab
export AWS_DEFAULT_REGION=ca-central-1
aws sts get-caller-identity
cd live/dev/ca-central-1/vpc
terragrunt init
terragrunt plan
# terragrunt apply # seulement en compte lab
Multi-units depuis un dossier parent :
cd live/dev/ca-central-1
terragrunt run --all plan
# terragrunt run --all apply --non-interactive # lab only
Notes : l’ancien run-all existe encore ; préférez terragrunt run --all. Gitignorez .terragrunt-cache/. Un state S3 par unit limite le blast radius.
Nettoyage :
cd live/dev/ca-central-1
terragrunt run --all destroy --non-interactive # lab only
Étape 6 — Check-list scale + day-2
| Check | Pourquoi |
|---|---|
| Un bucket state versionné + chiffrement | Rollback / forensic |
| Lock table (ou équivalent doc) | Éviter apply concurrents |
generate provider unique |
Plus de drift de versions AWS |
dependency explicites |
Ordre apply / destroy prévisible |
| Inputs par env, pas de secrets dans Git | SSM / Secrets Manager / CI OIDC |
CI : plan sur PR, apply sur main/env |
Même pattern que Terraform nu |
| Comptes séparés (voir multi-account) | Isolation blast radius |
Terragrunt scale horizontalement sans dupliquer le glue. Multi-compte : Organizations / Identity Center (wow-multi-account-org) + account.hcl par compte.
Erreurs fréquentes
| Symptôme | Cause probable | Correctif |
|---|---|---|
Could not find remote_state / mauvais key |
path_relative_to_include mal compris |
Affichez la key générée ; un state ≠ un env |
| Recreate massif au plan | Module source changé / Region | Fixez source (ref git tag) ; ca-central-1 partout |
dependency vide en plan |
Aval planifié avant amont | mock_outputs ou apply VPC d’abord |
| Cache stale | .terragrunt-cache vieux |
terragrunt clear / supprimer le cache unit |
| Double backend dans le module | backend.tf à la main + generate |
Backend uniquement via Terragrunt generate |
| Confusion workspace vs Terragrunt | Même mot « env » | Workspace = state sur 1 config ; TG = multi-root DRY |
FAQ
Terragrunt remplace-t-il Terraform ?
Non. Terragrunt orchestre Terraform. Les modules restent HCL Terraform.
Workspaces ou Terragrunt ?
Workspaces : petit lab, même compte, même config. Terragrunt : plusieurs stacks/envs/comptes, backends et inputs DRY. Les deux peuvent coexister, mais ne mélangez pas sans convention d’équipe.
Faut-il Terragrunt pour 2 roots ?
Souvent non. Introduisez-le quand la duplication backend/provider/tfvars devient douloureuse (règle empirique : ≥ 3 envs × ≥ 3 stacks).
run --all est-il dangereux ?
Oui en prod sans garde-fous. Bornez le chemin (cd sur un env), revue de plan, et idéalement un pipeline avec approbation. Jamais --all apply depuis la racine live/ « pour voir ».
OpenTofu + Terragrunt ?
Terragrunt peut cibler tofu selon la config/terraform_binary (vérifiez la doc de votre version). Les labs DEH restent sur terraform sauf besoin licence.
Pourquoi ca-central-1 ?
Region pédagogique DEH (Canada) : cohérence des tutos, latence, et tags homogènes dans les labs.
Quiz (5 questions)
1. Rôle principal de Terragrunt ?
– A. Remplacer le langage HCL
– B. Couche DRY : backend/provider, inputs, orchestration multi-units
– C. Remplacer AWS CloudFormation
2. Un remote_state S3 par unit sert surtout à ?
– A. Partager un seul state monolithe
– B. Isoler le blast radius et versionner chaque stack
– C. Éviter d’utiliser IAM
3. À quoi sert mock_outputs sur une dependency ?
– A. Contourner le plan en prod
– B. Permettre validate/plan de l’aval avant apply de l’amont
– C. Chiffrer le state
4. Commande moderne pour planifier tout un dossier d’units ?
– A. terraform workspace plan-all
– B. terragrunt run --all plan
– C. kubectl apply -f live/
5. Différence clé vs workspaces CLI ?
– A. Aucune
– B. Workspaces = multi-state même config ; Terragrunt = multi-root + glue DRY
– C. Workspaces gèrent les SCPs Organizations
Réponses : 1‑B · 2‑B · 3‑B · 4‑B · 5‑B
Points clés
- Terragrunt = scale DRY de Terraform, pas un nouveau DSL cloud.
root.hcl+generate+remote_state= fin du copier-coller backend/provider.dependency+run --all= graphe d’apply explicite.- Lab en
ca-central-1, secrets hors Git, destroy en fin de session.
Pour aller plus loin
- Docs officielles : terragrunt.gruntwork.io
- State backend S3
- Modules bases · Modules registry
- Workspaces (contraste)
- Multi-account Organizations
- OIDC GitHub → AWS (CI sans access keys)
- OpenTofu vs Terraform
Maillage série Terraform / WOW
| ← Contraste | Terraform workspace |
| State | Backend S3 + lock |
| Modules | Bases · Registry |
| WOW voisin | Multi-account org · Crossplane AWS |
| Hub | Terraform |
Meta publication (SEO)
- Title SEO : Terragrunt : scale Terraform multi-env (guide FR 2026)
- Meta description : Terragrunt 2026 : layout DRY multi-env, remote_state S3, generate, dependency et run –all. Lab ca-central-1, FAQ HowTo DEH.
- Focus keyword : terragrunt
- Secondary : terragrunt multi-env, remote_state, terragrunt run –all, dry terraform, root.hcl
- Image :
assets/web/devopelastichayway/cover-wow-terragrunt-scale-1200x630.webp(à générer) - Catégorie : WOW / Terraform · Niveau : Intermédiaire
- URL cible : https://devopelastichayway.com/tutoriels/wow-terragrunt-scale/
- Slug :
wow-terragrunt-scale· Publish : READY (feu vert Maître)
Sources : docs Terragrunt (include, generate, remote_state, dependency, run –all) ; HashiCorp Terraform ≥ 1.9 ; labs DEH ca-central-1. Revalidez la syntaxe de votre release avant prod.
Pour aller plus loin — hubs live
Retour parcours Catalogue Tutoriels — hub de la série et leçons sœurs.