Retour aux articles
5 min de lecture

Accélère Terraform avec Terragrunt, fini les apply interminables

Des state files séparés, plus de copier-coller, et fini de tout réappliquer à chaque fois. Terragrunt répare ce que Terraform refuse de faire.

TerraformTerragruntDevOpsIaC

Attendre 10 minutes pour un terraform apply qui vérifie 47 ressources alors que j’ai changé un paramètre de base de données. Ça me rend fou

Copier la même config backend dans 15 dossiers différents. À chaque fois

Les gens qui disent ‘on peut tout faire avec Terraform pur’ pendant qu’ils recréent Terragrunt en moins bien. Ok

Terragrunt tenant Terraform

Le problème que Terraform refuse de régler

Terraform marche bien pour un seul environnement. Dès que t’as du multi-environnement, multi-région, ou plusieurs trucs à gérer, ça part en vrille

Tu lances terraform apply dans un state file monolithique. Ça vérifie chaque ressource. T’as changé un record DNS? Cool, je vais vérifier ton VPC entier, chaque instance EC2, toutes tes bases RDS, et ce bucket S3 que t’as créé y’a 6 mois

Tu split en modules pour éviter le monolithe. Maintenant tu copies les configs backend, les définitions de variables, et les blocs provider partout. Le principe DRY part à la poubelle

Les puristes de Terraform disent ‘utilise juste les modules et les workspaces.’ Les workspaces partagent le même state file. Tu reviens au apply de 10 minutes. Les modules sans Terragrunt? Tu écris le même boilerplate dans chaque environnement:

# dev/main.tf
terraform {
  backend 's3' {
    bucket = 'my-terraform-state'
    key    = 'dev/terraform.tfstate'
    region = 'us-east-1'
  }
}

module 'vpc' {
  source = '../modules/vpc'
  environment = 'dev'
  cidr = '10.0.0.0/16'
}

# staging/main.tf
terraform {
  backend 's3' {
    bucket = 'my-terraform-state'
    key    = 'staging/terraform.tfstate'
    region = 'us-east-1'
  }
}

module 'vpc' {
  source = '../modules/vpc'
  environment = 'staging'
  cidr = '10.1.0.0/16'
}

# prod/main.tf
terraform {
  backend 's3' {
    bucket = 'my-terraform-state'
    key    = 'prod/terraform.tfstate'
    region = 'us-east-1'
  }
}

module 'vpc' {
  source = '../modules/vpc'
  environment = 'prod'
  cidr = '10.2.0.0/16'
}

Trois environnements, trois copies du même code. Tu changes ton nom de bucket S3? Tu mets à jour dans 47 endroits. T’en rates un? Ton state file finit au mauvais endroit

Ce que Terragrunt fait vraiment

Terragrunt te donne des state files séparés sans l’enfer du copier-coller

Une config backend dans la racine:

# root.hcl
remote_state {
  backend = 's3'
  config = {
    bucket = 'my-terraform-state'
    key    = '${path_relative_to_include()}/terraform.tfstate'
    region = 'us-east-1'
  }
}

Chaque environnement y fait référence:

# dev/terragrunt.hcl
include 'root' {
  path = find_in_parent_folders('root.hcl')
}

inputs = {
  environment = 'dev'
  cidr = '10.0.0.0/16'
}

C’est tout! Pas de duplication de bloc backend. Pas de copier-coller. Le chemin du state file est automatique, basé sur la structure de dossiers

Tu changes ta config backend une fois, ça s’applique partout. Tu veux ajouter le chiffrement? Une ligne dans la config racine!

Les dépendances qui marchent vraiment

Terraform a depends_on. C’est manuel et tu l’oublies jusqu’à ce que tout casse

Terragrunt a des blocs dependency explicites:

# app/terragrunt.hcl
dependency 'vpc' {
  config_path = '../vpc'
}

dependency 'database' {
  config_path = '../database'
}

inputs = {
  vpc_id = dependency.vpc.outputs.vpc_id
  db_endpoint = dependency.database.outputs.endpoint
}

Tu lances terragrunt apply dans le dossier app. Ça sait qu’il faut le VPC et la database d’abord. Ça les applique dans l’ordre. Pas d’orchestration manuelle

L’output d’un module alimente directement le suivant. Pas de passage de variables manuel. Pas besoin d’espérer que t’as retenu le bon ordre

Lance une fois, pas 47 fois

Tu split ton infra en morceaux logiques:

  • vpc/ a son propre state
  • database/ a son propre state
  • app/ a son propre state

Tu changes la database? terragrunt apply dans database/ seulement. Ça prend 30 secondes au lieu de 10 minutes

Le state file du VPC est pas touché. Le state file de l’app est pas touché. Seulement ce que t’as changé est vérifié!

J’ai split un setup Terraform monolithique en modules Terragrunt. Les temps d’apply sont passés de 8 minutes à moins d’une minute pour la plupart des changements. Le VPC a pas changé depuis des mois, pourquoi je le vérifierais?

Les ‘on peut faire ça avec Terraform’

Ils ont raison. Techniquement tu peux. Tu vas écrire des scripts bash pour générer les configs backend. Tu vas utiliser des Makefiles pour lancer les applies dans le bon ordre. Tu vas créer ta propre gestion de dépendances

Tu recrées Terragrunt. En moins bien

J’ai vu des équipes faire ça. Ils finissent avec:

  • Un script bash qui template les configs backend
  • Un script Python qui parse les outputs et génère des fichiers de variables
  • Un Makefile avec 47 targets dans le bon ordre
  • Une doc qui date de 3 mois
  • Les nouveaux devs qui pigent rien à comment ça marche

Ou tu peux installer Terragrunt et écrire quelques fichiers terragrunt.hcl

Structure réelle qui scale

infrastructure/
├── root.hcl                    # Config racine, paramètres backend
├── dev/
│   ├── vpc/
│   │   └── terragrunt.hcl
│   ├── database/
│   │   └── terragrunt.hcl
│   └── app/
│       └── terragrunt.hcl
├── staging/
│   ├── vpc/
│   │   └── terragrunt.hcl
│   ├── database/
│   │   └── terragrunt.hcl
│   └── app/
│       └── terragrunt.hcl
└── modules/
    ├── vpc/
    ├── database/
    └── app/

Chaque terragrunt.hcl fait 10-20 lignes. Le vrai code Terraform vit dans modules/. Pas de duplication

Tu veux appliquer tout dans dev? terragrunt run-all apply depuis dev/. Ça calcule les dépendances et les lance dans l’ordre

Tu veux appliquer juste la database? cd dev/database && terragrunt apply. Ça prend quelques secondes

Ce que Terragrunt corrige pas

HCL est toujours limité. Tu peux pas faire de la logique complexe sans bidouilles

La gestion du state de Terraform est toujours fragile. Terragrunt la rend juste gérable

Les modules du registry Terraform sont toujours inégaux. Terragrunt répare pas les mauvais modules

Mais ça répare les problèmes qui me donnaient envie de lâcher Terraform:

  • Attendre une éternité pour les applies
  • Copier la config partout
  • Tracker les dépendances manuellement
  • Espérer que j’ai pas cassé la prod en oubliant le bon ordre d’apply

Quand pas utiliser Terragrunt

Petits projets avec un seul environnement. Utilise juste Terraform. Terragrunt ajoute de la complexité dont tu n’as pas besoin

Si ton équipe refuse d’apprendre quoi que ce soit de nouveau. Terragrunt a une courbe d’apprentissage, pas abrupte, mais elle existe

Si tu déploies sur 47 clouds différents avec des patterns complètement différents. Terragrunt s’attend à un peu de structure

Commencer

Installe Terragrunt:

# Debian/Ubuntu
wget https://github.com/gruntwork-io/terragrunt/releases/latest/download/terragrunt_linux_amd64
sudo mv terragrunt_linux_amd64 /usr/local/bin/terragrunt
sudo chmod +x /usr/local/bin/terragrunt

# Arch
yay -S terragrunt

Crée un root.hcl:

remote_state {
  backend = 's3'
  config = {
    bucket = 'your-terraform-state'
    key    = '${path_relative_to_include()}/terraform.tfstate'
    region = 'us-east-1'
    encrypt = true
  }
}

Crée une config d’environnement:

# dev/vpc/terragrunt.hcl
include 'root' {
  path = find_in_parent_folders('root.hcl')
}

terraform {
  source = '../../modules/vpc'
}

inputs = {
  environment = 'dev'
  cidr = '10.0.0.0/16'
}

Lance-le:

cd dev/vpc
terragrunt init
terragrunt apply

Ton backend est configuré automatiquement. Ton state file est au bon endroit. Pas besoin de copier-coller

J’ai passé un an à me battre avec les limitations de Terraform. J’ai passé une semaine à apprendre Terragrunt. Je reviens pas en arrière

La réalité est souvent plus nuancée. Moi, la nuance ça m'ennuie. Je préfère la clarté.

Commentaires