Aller au contenu
Infrastructure as Code medium
🔐 Alerte sécurité — Incident supply chain Trivy : lire mon analyse de l'attaque

Structurer un live repo Terragrunt avec root.hcl et _env

8 min de lecture

logo terragrunt

Votre premier unit Terragrunt fonctionne, mais comment organiser un depot entier quand vous avez plusieurs composants et environnements ? Sans structure, vous finissez vite avec des dossiers dupliques et des conventions implicites que personne ne maitrise vraiment.

Ce guide vous montre une structure minimale avec root.hcl, un dossier _env et deux units foo et bar dans le meme environnement dev. L’objectif est simple : centraliser ce qui est commun, laisser dans chaque unit uniquement ce qui varie, puis garder une arborescence qui reste lisible a mesure que le repo grandit.

  • Comprendre le role de root.hcl et d’un dossier _env
  • Structurer plusieurs units avec des includes coherents
  • Eviter la duplication inutile entre units d’un meme environnement
  • Verifier qu’un meme motif est reutilise sans copier-coller

Voici l’organisation recommandee :

  • Répertoirelab-b/
    • Répertoiremodules/
      • Répertoirewrite-file/
        • main.tf
    • Répertoirelive/
      • root.hcl
      • Répertoire_env/
        • write-file.hcl
      • Répertoiredev/
        • Répertoirefoo/
          • terragrunt.hcl
        • Répertoirebar/
          • terragrunt.hcl

Chaque niveau a un role different :

  • root.hcl porte les conventions globales du repo ;
  • _env/write-file.hcl factorise ce qui est commun a une famille de units ;
  • chaque unit garde seulement ses variations propres.

Cet exemple repose sur le meme module minimal que le premier guide. Placez-le dans modules/write-file/main.tf :

terraform {
required_version = ">= 1.6.0"
required_providers {
local = {
source = "hashicorp/local"
version = "~> 2.5"
}
}
}
variable "filename" {
type = string
}
variable "content" {
type = string
}
resource "local_file" "this" {
filename = var.filename
content = var.content
}
output "file_path" {
value = local_file.this.filename
}
output "content" {
value = local_file.this.content
}

Dans ce premier pattern, root.hcl reste volontairement petit :

locals {
stack_name = "dev"
}

L’interet n’est pas la quantite de logique stockee ici. L’interet est d’avoir un point central dans lequel vous pourrez ensuite placer des conventions de backend, des locals communs ou des blocs generate quand le repo grandit.

Copiez exactement ce contenu dans live/root.hcl.

Le dossier _env sert a factoriser ce qui est commun a plusieurs units du meme type. Voici le fichier partage :

locals {
module_source = "${dirname(find_in_parent_folders("root.hcl"))}/../modules/write-file"
}
inputs = {
content_prefix = "hello"
}

Ce pattern apporte deux benefices immediats :

  • les units ne repetent plus leur source de module ;
  • les inputs communs sont centralises dans un seul endroit.

Copiez exactement ce contenu dans live/_env/write-file.hcl.

Une unit comme foo peut alors se reduire a ceci :

include "root" {
path = find_in_parent_folders("root.hcl")
expose = true
}
include "env" {
path = "${get_terragrunt_dir()}/../../_env/write-file.hcl"
expose = true
}
terraform {
source = include.env.locals.module_source
}
inputs = {
filename = "${get_terragrunt_dir()}/foo.txt"
content = "${include.env.inputs.content_prefix} from foo in ${include.root.locals.stack_name}"
}

Le dossier bar suit exactement la meme structure, avec seulement la variation utile sur le nom du fichier et sur le contenu.

Voici le contenu complet de live/dev/bar/terragrunt.hcl :

include "root" {
path = find_in_parent_folders("root.hcl")
expose = true
}
include "env" {
path = "${get_terragrunt_dir()}/../../_env/write-file.hcl"
expose = true
}
terraform {
source = include.env.locals.module_source
}
inputs = {
filename = "${get_terragrunt_dir()}/bar.txt"
content = "${include.env.inputs.content_prefix} from bar in ${include.root.locals.stack_name}"
}

Ce decoupage est utile parce qu’il rend explicite la provenance de chaque chose :

  • ce qui vient du niveau racine du repo ;
  • ce qui vient d’une famille de units partagees ;
  • ce qui reste specifique a une unit donnee.

Quand vous relisez le repo plusieurs semaines plus tard, ou quand une autre personne rejoint l’equipe, cette separation reduit beaucoup le temps de lecture.

  1. Creer un root.hcl minimal

    Commencez par y placer un ou deux locals globaux faciles a comprendre.

    Verification : live/root.hcl existe deja avant de passer a l’etape suivante.

  2. Ajouter un dossier _env

    Placez-y les morceaux communs a plusieurs units d’un meme type : source de module, inputs partages, conventions simples.

    Verification : live/_env/write-file.hcl existe et contient a la fois locals et inputs.

  3. Faire inclure root et env dans chaque unit

    Utilisez include ... { expose = true } pour relire les valeurs partagees.

    Verification : foo/terragrunt.hcl et bar/terragrunt.hcl contiennent chacun deux blocs include.

  4. Garder dans chaque unit seulement les variations utiles

    Le nom du fichier, une valeur d’input, un identifiant d’environnement ou de composant.

  5. Verifier avec terragrunt run --all apply

    Verification : foo.txt et bar.txt sont bien crees avec un contenu different mais base sur le meme prefixe centralise.

Si tout est en place, l’execution confirme que :

  • deux units peuvent partager une meme source de module ;
  • la source peut etre resolue depuis un fichier partage sous _env ;
  • root.hcl peut exposer des locals reutilises dans les units ;
  • les variations finales restent lisibles dans chaque unit.
SymptomeCause probableSolution
include.env.locals... ne marche pasexpose = true manqueAjouter expose = true sur l’include concerne
Le chemin du module casseLa resolution depuis root.hcl est fausseVerifier le chemin reel et la profondeur du repo
Les units dupliquent encore trop de logiqueTrop d’inputs ou de source repetes dans chaque unitRemonter ce qui est commun dans _env
  • root.hcl porte les conventions globales du live repo.
  • Un dossier _env aide a factoriser les blocs communs a plusieurs units.
  • Chaque unit ne doit garder que ses variations reelles.
  • Les include avec expose = true rendent la provenance des valeurs plus lisible.
  • Cette structure devient vite rentable des que plusieurs units partagent le meme motif.

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracing. Aujourd'hui, ce site ne couvre même pas mes frais d'hébergement, d'électricité, de matériel, de logiciels, mais surtout de cafés.

Un soutien régulier, même symbolique, m'aide à garder ces ressources gratuites et à continuer de produire des guides de qualité. Merci pour votre appui.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn