Aller au contenu
English
English
Infrastructure as Code medium

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 dépôt 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 même 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
  • Éviter la duplication inutile entre units d'un même environnement
  • Vérifier qu'un même motif est reutilise sans copier-coller

Voici l'organisation recommandée :

  • 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 même 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'intérêt n'est pas la quantité de logique stockée ici. L'intérêt 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 même 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 bénéfices immediats :

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

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

Une unit comme foo peut alors se réduire 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 même 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 découpage 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 partagées ;
  • ce qui reste spécifique a une unit donnée.

Quand vous relisez le repo plusieurs semaines plus tard, ou quand une autre personne rejoint l'équipe, cette séparation réduit beaucoup le temps de lecture.

  1. Créer un root.hcl minimal

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

    Verification : live/root.hcl existe déjà avant de passer a l'étape suivante.

  2. Ajouter un dossier _env

    Placez-y les morceaux communs a plusieurs units d'un même 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 partagées.

    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. Vérifier avec terragrunt run --all apply

    Verification : foo.txt et bar.txt sont bien créés avec un contenu different mais base sur le même préfixe centralise.

Si tout est en place, l'exécution confirme que :

  • deux units peuvent partager une même source de module ;
  • la source peut être résolue depuis un fichier partage sous _env ;
  • root.hcl peut exposer des locals reutilises dans les units ;
  • les variations finales restent lisibles dans chaque unit.
SymptômeCause probableSolution
include.env.locals... ne marche pasexpose = true manqueAjouter expose = true sur l'include concerne
Le chemin du module casseLa résolution depuis root.hcl est fausseVérifier le chemin réel 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 réelles.
  • Les include avec expose = true rendent la provenance des valeurs plus lisible.
  • Cette structure devient vite rentable des que plusieurs units partagent le même motif.

Ce site vous est utile ?

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

Je maintiens ce site gratuitement, sans publicité, sans profilage et sans compte à créer. Un soutien, même symbolique, m'aide à couvrir l'hébergement et à garder ces ressources gratuites. Merci pour votre appui.

Le formulaire ne s'affiche pas ? Ouvrir Ko-fi dans un onglet.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn