Quand un terragrunt apply échoue, commencez par savoir où Terragrunt travaille
réellement : terragrunt info print donne le dossier d'exécution, .terragrunt-cache
contient la copie de travail et le state local, et --log-level debug montre
les étapes. Cette leçon donne une méthode de diagnostic en cinq outils : le
cache, info print, les logs, les chemins relatifs et les hooks. Elle a été
rejouée avec Terragrunt 1.1.6 et OpenTofu 1.13.1, sur un unit unique pour
isoler chaque mécanisme.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Expliquer le rôle de
.terragrunt-cacheet pourquoi on n'y exécute pas depuis le dossier source - Lire le contexte réel d'exécution avec
terragrunt info print - Régler
--log-levelet--log-formatsans modifier le code - Ancrer les chemins relatifs sur des repères stables
- Écrire un
before_hook, unafter_hooket unerror_hook - Vider le cache dans le bon ordre, sans laisser de ressources orphelines
Quel exemple minimal utilise-t-on ?
Section intitulée « Quel exemple minimal utilise-t-on ? »Un seul unit, app, qui écrit un fichier hello.txt avec le module write-file.
Un unit est un dossier qui contient un terragrunt.hcl et pilote un module
Terraform ou OpenTofu. Ici, aucun backend distant n'est configuré, ce qui compte
pour la suite : le state sera local.
Répertoirelab-debug/
Répertoiremodules/
Répertoirewrite-file/
- main.tf
Répertoirelive/
Répertoiredev/
Répertoireapp/
- terragrunt.hcl
Fichier 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}Fichier live/dev/app/terragrunt.hcl :
terraform { source = "../../../modules/write-file"}
inputs = { filename = "${get_terragrunt_dir()}/hello.txt" content = "hello from lab a"}Comment provoquer un premier run ?
Section intitulée « Comment provoquer un premier run ? »Placez-vous dans live/dev/app et lancez un apply. Sur un unit seul,
--non-interactive supprime les questions de Terragrunt, mais pas la confirmation
d'OpenTofu : il faut y ajouter -auto-approve.
terragrunt --non-interactive apply -auto-approveLe résultat est double : hello.txt apparaît dans le dossier du unit et un
dossier .terragrunt-cache apparaît à côté de terragrunt.hcl. Terragrunt
n'exécute pas le moteur depuis votre dossier source : il prépare un
répertoire de travail intermédiaire dans ce cache.
Que contient terragrunt info print ?
Section intitulée « Que contient terragrunt info print ? »terragrunt info print affiche, sans rien exécuter, le contexte réel de
l'exécution : c'est le premier diagnostic à lancer. La sortie est un objet JSON
à six clés.
| Clé | Contenu |
|---|---|
config_path | Le terragrunt.hcl chargé |
download_dir | Le chemin de .terragrunt-cache |
working_dir | Le dossier réel depuis lequel le module s'exécute |
iam_role | Le rôle IAM configuré, s'il y en a un |
terraform_binary | Le moteur utilisé (tofu ou terraform) |
terraform_command | La commande en cours (print ici) |
Retenez surtout working_dir : il répond à la question « où mon module
s'exécute-t-il vraiment ? », que le dossier visible dans le dépôt ne
permet pas de deviner.
Que trouve-t-on dans .terragrunt-cache ?
Section intitulée « Que trouve-t-on dans .terragrunt-cache ? »Le cache n'est pas du bruit : c'est le lieu concret de l'exécution. Listez-le sur trois niveaux :
find .terragrunt-cache -maxdepth 3 | sortVous y retrouvez la copie du module (main.tf), le terragrunt.hcl, les dossiers
.terraform et .terraform.lock.hcl, les manifestes Terragrunt
(.terragrunt-module-manifest, .terragrunt-source-manifest,
.terragrunt-source-version) et, sans backend distant, le state local
terraform.tfstate.
Cette présence du state a une conséquence directe : vider le cache supprime le
state. Sans remote_state, un unit dont on a effacé le cache ne sait plus
qu'il a créé ses ressources.
Le listing peut contenir aussi hello.txt, alors que le fichier est créé dans
le dossier du unit (get_terragrunt_dir()). C'est une recopie : rejoué, un
find .terragrunt-cache -name hello.txt ne trouve rien juste après le premier
apply, puis trouve le fichier après la commande suivante (plan). Terragrunt
recopie à chaque exécution le contenu du dossier du unit dans le cache ; la
copie est identique à l'original (cmp ne signale aucune différence) mais c'est un
autre fichier. Le vrai fichier reste celui du dossier du unit.
Comment régler les logs ?
Section intitulée « Comment régler les logs ? »Le niveau et le format des logs se règlent sans toucher au code. Pour enrichir le diagnostic, lancez :
terragrunt --log-level debug info printLa sortie de debug montre la version de Terragrunt, la détection du moteur
(tofu version: 1.13.1), la ligne Reading Terragrunt config file at ./terragrunt.hcl
et le moment où Setting working directory to ./.terragrunt-cache/<h1>/<h2>.
Commencer par info print en debug permet de voir le contexte sans lancer un
apply de plus.
Les valeurs acceptées ont été toutes vérifiées. Une valeur inconnue (verbose,
bidule) est rejetée avec le code 1.
| Option | Valeurs acceptées |
|---|---|
--log-level | stderr, stdout, error, warn, info, debug, trace |
--log-format | key-value, bare, pretty, json |
Le format key-value donne time=... level=debug msg=..., le format json un
objet par ligne ({"time":...,"level":"debug","working-dir":...,"msg":...}) et
bare des lignes de la forme DEBU[0000] .... Pour un format sur mesure,
--log-custom-format '%level %msg' produit par exemple
debug Terragrunt Version: 1.1.6. La variable TG_LOG_LEVEL=debug est
équivalente à l'option.
Pourquoi les chemins relatifs piègent-ils ?
Section intitulée « Pourquoi les chemins relatifs piègent-ils ? »Le module s'exécute depuis le répertoire de travail du cache, pas depuis le dossier visible. Un chemin relatif écrit en supposant un autre dossier courant vise donc le mauvais emplacement. C'est la raison d'être de cette ligne :
filename = "${get_terragrunt_dir()}/hello.txt"get_terragrunt_dir() ancre le chemin sur le dossier du unit. Pour les
sources de modules et les fichiers racine, partez de repères stables plutôt que
de « là où la commande est lancée » : get_terragrunt_dir() pour le dossier
du unit, find_in_parent_folders("root.hcl") pour retrouver une racine connue.
Comment écrire des hooks ?
Section intitulée « Comment écrire des hooks ? »Un hook est une commande que Terragrunt exécute autour du moteur. Il se
déclare dans le bloc terraform du unit. Trois types existent : before_hook
(avant le moteur), after_hook (après) et error_hook (quand une erreur
correspond à un motif).
Le schéma se lit de gauche à droite : le trait épais est le chemin de succès, les
traits fins le chemin d'échec. Un after_hook ne s'exécute après un échec que
si run_on_error = true. Pour voir les trois hooks agir, il faut une erreur provoquée à la demande,
sinon l'error_hook ne se déclenche jamais. Ajoutez d'abord à la fin de
modules/write-file/main.tf une variable fail et une precondition, un
contrôle que le moteur évalue avant de créer la ressource :
variable "fail" { type = bool default = false}
resource "terraform_data" "garde_fou" { lifecycle { precondition { condition = !var.fail error_message = "Expected failure: la variable fail vaut true" } }}La condition doit citer un objet de la configuration (ici var.fail). Avec
condition = false, OpenTofu refuse le module dès init (Invalid precondition expression) et aucun hook ne s'exécute. Ensuite, remplacez le bloc
terraform du terragrunt.hcl du unit par le suivant : il reprend le source
et ajoute les trois hooks.
terraform { source = "../../../modules/write-file"
before_hook "avant" { commands = ["apply", "plan"] execute = ["echo", "HOOK-AVANT dans ${get_terragrunt_dir()}"] }
after_hook "apres" { commands = ["apply"] execute = ["echo", "HOOK-APRES"] run_on_error = true }
error_hook "erreur" { commands = ["apply"] execute = ["echo", "HOOK-ERREUR"] on_errors = [".*Expected failure.*"] }}Au rejeu, le before_hook affiche Executing hook: avant puis
HOOK-AVANT dans <dossier du unit> avant le moteur, et l'after_hook affiche
Executing hook: apres puis HOOK-APRES. Pour provoquer l'échec, lancez
TF_VAR_fail=true terragrunt --non-interactive apply -auto-approve. Quand tofu apply échoue, l'ordre observé est avant, puis
apres, puis erreur : l'after_hook à run_on_error = true passe
avant l'error_hook, qui n'affiche HOOK-ERREUR que si le message d'erreur
correspond à on_errors. Avec une autre erreur, seul HOOK-APRES s'affiche. Avec
run_on_error = false, l'after_hook est sauté et l'error_hook s'exécute
quand même. Dans tous les cas, le code de retour 1 est conservé : un hook ne
masque pas l'échec.
Les hooks entourent la commande tofu apply, pas l'initialisation. Si tofu init
échoue (erreur de syntaxe HCL dans le module, par exemple), aucun hook ne
s'exécute, pas même avant, et la commande rend le code 1. Pour voir les trois
messages, il faut une erreur qui survient pendant apply, comme la
precondition ajoutée plus haut, dont le message contient Expected failure.
L'option --no-hooks n'est pas globale : elle s'écrit sur run
(terragrunt run --no-hooks -- plan) et exige l'expérience optional-hooks
(--experiment optional-hooks), sans quoi elle échoue avec le code 1.
Pour déboguer un hook, vérifiez d'abord le working_dir avec info print,
activez --log-level debug, utilisez des chemins ancrés par get_terragrunt_dir()
et faites afficher les erreurs clairement.
Comment nettoyer le cache sans perdre le state ?
Section intitulée « Comment nettoyer le cache sans perdre le state ? »Pour repartir proprement, le cache se supprime avec une commande simple :
find . -type d -name '.terragrunt-cache' -prune -exec rm -rf {} +Mais l'ordre compte. Sans backend distant, le state vit dans le cache : si
vous le videz avant d'arrêter le unit, la destruction ne trouve plus rien à
détruire. Rejoué dans cet ordre, destroy répond Destroy complete! Resources: 0 destroyed, code 0, alors que hello.txt et .terraform.lock.hcl restent sur
le disque ; un nouvel apply recrée alors la ressource (1 added). Dans le bon
ordre (appliquer, arrêter, puis vider le cache), destroy rend Resources: 1 destroyed (2 avec le garde-fou de la section sur les hooks) et hello.txt
disparaît.
Comment jouer et vérifier le scénario ?
Section intitulée « Comment jouer et vérifier le scénario ? »-
Appliquer le unit
Fenêtre de terminal terragrunt --non-interactive apply -auto-approveVérification :
hello.txtet.terragrunt-cacheexistent. -
Afficher le contexte Terragrunt
Fenêtre de terminal terragrunt info printVérification : la sortie contient
config_path,download_diretworking_dir. -
Activer les logs de debug
Fenêtre de terminal terragrunt --log-level debug info printVérification : vous voyez la lecture du
terragrunt.hclet la définition du working directory. -
Lister le cache
Fenêtre de terminal find .terragrunt-cache -maxdepth 3 | sortVérification :
terraform.tfstatefigure dans la liste. -
Ajouter le garde-fou et les hooks, puis appliquer
Ajoutez la variable
failet lapreconditionàmodules/write-file/main.tf, remplacez le blocterraformdu unit par celui des trois hooks, puis lancez :Fenêtre de terminal terragrunt --non-interactive apply -auto-approveVérification : les lignes
Executing hook: avant,HOOK-AVANT dans ...,Apply complete! Resources: 1 added,Executing hook: apres,HOOK-APRESapparaissent dans cet ordre, code 0. -
Provoquer l'échec pour voir
erreurFenêtre de terminal TF_VAR_fail=true terragrunt --non-interactive apply -auto-approveVérification :
Error: Resource precondition failedetExpected failure: la variable fail vaut true, avecExecuting hook: avant, puisapres(HOOK-APRES), puiserreur(HOOK-ERREUR), et le code de retour 1. -
Arrêter le unit, puis seulement ensuite vider le cache
Fenêtre de terminal terragrunt run --all --non-interactive -- destroyfind . -type d -name '.terragrunt-cache' -prune -exec rm -rf {} +Vérification :
Destroy complete! Resources: 2 destroyed(le fichier et le garde-fou),hello.txtdisparaît, puis le cache est supprimé. Cette formerun --allest celle qui a été rejouée. La forme sur un unit seul avec l'approbation automatique n'a pas été rejouée telle quelle (l'environnement de test ne permettait pas de l'exécuter), et--non-interactiven'ajoute pas cette approbation sur un unit seul.
Erreurs fréquentes
Section intitulée « Erreurs fréquentes »| Symptôme | Cause probable | Solution |
|---|---|---|
| Le module semble s'exécuter dans un dossier incompréhensible | Terragrunt travaille dans .terragrunt-cache | Lancer terragrunt info print |
| Un chemin relatif fonctionne mal | Le chemin suppose un mauvais dossier courant | Repartir de get_terragrunt_dir() ou d'une racine stable |
destroy détruit 0 ressource alors que hello.txt existe | Cache vidé avant l'arrêt, donc state local perdu | Détruire d'abord, vider le cache ensuite |
| Les logs sont trop pauvres | Niveau par défaut trop bas | Relancer avec --log-level debug |
--no-hooks rend le code 1 | L'expérience optional-hooks n'est pas activée | Ajouter --experiment optional-hooks, sur run |
À retenir
Section intitulée « À retenir ».terragrunt-cacheest le lieu d'exécution ; sans backend distant, il contient aussi le state.terragrunt info printdonne six clés, dontworking_dir: c'est le premier diagnostic.--log-levelacceptestderràtrace,--log-formatkey-value,bare,prettyoujson.- Un hook s'écrit en
before_hook,after_hook(avecrun_on_error) ouerror_hook, et ne masque pas le code de retour. - Détruisez le unit avant de vider le cache quand le state est local.
Contrôle de connaissances
Section intitulée « Contrôle de connaissances »Six questions tirées sur huit : le rôle du cache, info print, les valeurs de --log-level, les hooks et l'ordre destroy puis nettoyage.
Contrôle de connaissances
Validez vos connaissances avec ce quiz interactif
Informations
- Le chronomètre démarre au clic sur Démarrer
- Questions à choix multiples, vrai/faux et réponses courtes
- Vous pouvez naviguer entre les questions
- Les résultats détaillés sont affichés à la fin
Lance le quiz et démarre le chronomètre
Vérification
(0/0)Score par domaine
Un domaine regroupe plusieurs guides et reçoit plusieurs questions : son score est plus fiable qu'un score par thème, qui porte souvent sur une seule question.
Bilan
Points forts
Aucun sujet réussi à 80 % sur au moins deux questions pour l’instant.
Points faibles
Aucun sujet sous le seuil de réussite.
À faire ensuite
Des indices pour retenter votre chance ?
Continuer le cours : Terragrunt : catalogues, scaffold et industrialisation
Nouveau quiz complet avec des questions aléatoires
Retravailler uniquement les questions ratées
Retour à la liste des certifications