Terragrunt : scale Terraform multi-env

À la fin de ce tutoriel, vous structurerez un repo Terragrunt multi-environnements : root.hcl partagé, units DRY (live/<env>/<region>/<unit>), generate provider/backend, remote_state S3 par unit, dependency entre stacks, et terragrunt run --all — lab safe en ca-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-1

Slug : 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

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_parameter et 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 un plan de 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

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.

← Catalogue Tutoriels

Pour aller plus loin — hubs live

Retour parcours Catalogue Tutoriels — hub de la série et leçons sœurs.