
Un fichier .tfvars fournit des valeurs de variables sans toucher au code :
une configuration, plusieurs environnements. C'est simple, mais deux choses
piègent : l'ordre de précédence exact quand plusieurs sources se
contredisent, et le sort d'une variable non déclarée, qui n'échoue pas de la
même façon selon d'où elle vient. Ce guide traite le chargement automatique, la
précédence, ce piège, les types complexes et le cas des secrets.
Tous les comportements ont été vérifiés sur Terraform v1.15.4.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Le chargement automatique des
terraform.tfvarset*.auto.tfvars - L'ordre de précédence exact (avec
tfvars.jsonet l'ordre lexical) - Le piège de la variable non déclarée : warning ou erreur selon la source
- Les types complexes en fichier et en ligne de commande (JSON)
- Le cas des secrets, et pourquoi tfvars finit dans le state
Prérequis
Section intitulée « Prérequis »- Les variables d'entrée (variables Terraform)
- Terraform 1.15.x, la série stable courante
Le chargement automatique
Section intitulée « Le chargement automatique »Terraform charge sans argument quatre familles de fichiers, s'ils existent :
terraform.tfvars, terraform.tfvars.json, et tout *.auto.tfvars ou
*.auto.tfvars.json. Un fichier au nom quelconque (prod.tfvars) n'est pas
chargé automatiquement : il faut le passer par -var-file.
region = "eu-west-3"replicas = 3tags = { equipe = "infra", env = "prod" }Un .tfvars ne contient que des assignations : pas de bloc variable,
resource ni locals. Sa version JSON est un objet dont les clés sont les noms
de variables :
{ "region": "eu-west-3", "replicas": 3 }L'ordre de précédence, du plus faible au plus fort
Section intitulée « L'ordre de précédence, du plus faible au plus fort »Quand plusieurs sources donnent une valeur à la même variable, Terraform les applique dans un ordre fixe :
| Rang | Source |
|---|---|
| 1 | le default du bloc variable |
| 2 | la variable d'environnement TF_VAR_<nom> |
| 3 | le fichier terraform.tfvars |
| 4 | le fichier terraform.tfvars.json |
| 5 | les *.auto.tfvars (et .json), en ordre lexical |
| 6 | les options -var / -var-file et les variables HCP Terraform |
Trois précisions que beaucoup de guides ratent. D'abord, terraform.tfvars.json
est un niveau distinct au-dessus de terraform.tfvars : si les deux fournissent
la même variable, la variante JSON gagne. Ensuite, les *.auto.tfvars sont
chargés en ordre lexical, pas « alphabétique » : l'ordre compare les octets,
donc Z.auto.tfvars passe avant a.auto.tfvars, et 20-x après 10-y. Enfin,
les variables de workspace HCP Terraform sont au même niveau que la ligne de
commande, tout en haut.
Le piège : la variable non déclarée
Section intitulée « Le piège : la variable non déclarée »Voici le manque le plus coûteux, et le « faux diagnostic » que ce sujet promet
d'éviter. Une valeur affectée à une variable sans bloc variable
correspondant ne se comporte pas de la même façon selon sa source :
- dans un fichier
.tfvars: un simple avertissement, leplanréussit ; - via
-var: une erreur, leplanéchoue ; - via
TF_VAR_: silencieusement ignorée, aucun message.
# faute de frappe dans terraform.tfvars : replika au lieu de replicasterraform planWarning: Value for undeclared variableLes types complexes, en fichier et en ligne de commande
Section intitulée « Les types complexes, en fichier et en ligne de commande »Un .tfvars accepte naturellement listes, maps et objets :
zones = ["a", "b", "c"]tags = { env = "prod", equipe = "infra" }En ligne de commande, c'est plus subtil : passer une liste, une map ou un
objet via -var ou TF_VAR_ exige une syntaxe JSON valide, en respectant
l'échappement du shell :
terraform apply -var 'zones=["a","b","c"]'Ne passer que des scalaires en -var et réserver les structures aux fichiers est
souvent plus lisible.
Variable sans valeur : le mode non interactif échoue
Section intitulée « Variable sans valeur : le mode non interactif échoue »Une variable sans default et qu'aucune source n'alimente déclenche, sur un
poste de travail, une demande interactive. Mais en automatisation, avec
-input=false (le mode des pipelines), la même configuration échoue :
terraform plan -input=false# Error: No value for required variableC'est une cause classique d'échec en CI qui « marche pourtant en local ».
Fournissez toujours les variables requises par un fichier, un -var ou un
TF_VAR_ dans une chaîne d'automatisation.
Les secrets : tfvars finit dans le state
Section intitulée « Les secrets : tfvars finit dans le state »Un .tfvars ne doit jamais contenir de secret committé, mais le problème va
plus loin : une valeur fournie par un .tfvars ou par TF_VAR_ finit dans
le fichier d'état, en clair, même si la variable est sensitive. sensitive
ne masque que l'affichage.
Le seul mécanisme qui exclut réellement une valeur du state et du plan est
ephemeral = true (Terraform 1.10+). Pour un secret durable, préférez un
gestionnaire de secrets et une variable éphémère, plutôt qu'un .tfvars, même
gitignoré.
Repasser un fichier auto-chargé avec -var-file
Section intitulée « Repasser un fichier auto-chargé avec -var-file »-var-file n'est pas réservé aux fichiers non auto-chargés. On peut très bien
repasser explicitement un fichier déjà chargé automatiquement, ou en cumuler
plusieurs, le dernier fourni l'emportant :
terraform apply -var-file="production.auto.tfvars"terraform apply -var-file="base.tfvars" -var-file="prod.tfvars"Dépannage
Section intitulée « Dépannage »Ces symptômes viennent presque tous de la précédence ou d'une variable non déclarée.
| Symptôme | Cause | Solution |
|---|---|---|
Une valeur de .tfvars semble ignorée | Un *.auto.tfvars ou un -var la surcharge | Vérifier la précédence ; -var gagne toujours |
Warning: Value for undeclared variable | Une variable d'un .tfvars sans bloc variable | Corriger le nom, ou déclarer la variable |
Error: Value for undeclared variable | La même faute, mais via -var | Corriger le nom passé en ligne de commande |
No value for required variable en CI | -input=false et aucune source pour une variable requise | Fournir la valeur par fichier, -var ou TF_VAR_ |
| Un secret apparaît dans le state | tfvars et TF_VAR_ finissent en clair dans l'état | Chiffrer le state, ou utiliser ephemeral |
À retenir
Section intitulée « À retenir »- Sont auto-chargés :
terraform.tfvars,terraform.tfvars.json, et les*.auto.tfvars(.json). Un autre nom passe par-var-file. - Précédence :
default<TF_VAR_<terraform.tfvars<terraform.tfvars.json<*.auto.tfvars(ordre lexical) <-var/ HCP. - Variable non déclarée : warning en fichier, erreur en
-var, ignorée enTF_VAR_. Une faute de frappe dans un.tfvarsne casse rien. - Les types complexes en
-varexigent une syntaxe JSON. -input=falseéchoue sur une variable requise sans valeur.- Une valeur de
.tfvarsouTF_VAR_finit dans le state ; seulephemerall'en exclut.
FAQ : questions fréquentes
Section intitulée « FAQ : questions fréquentes »Les questions ci-dessous reprennent les confusions les plus fréquentes sur les tfvars : la précédence, la variable non déclarée, et les secrets.
Du plus faible au plus fort
- le
defaultdu blocvariable TF_VAR_<nom>terraform.tfvarsterraform.tfvars.json- les
*.auto.tfvars(.json), en ordre lexical -var,-var-fileet les variables HCP Terraform
Les points ratés
terraform.tfvars.json est un niveau distinct au-dessus de terraform.tfvars. Et un *.auto.tfvars l'emporte sur un TF_VAR_ exporté.Deux niveaux, pas un
Vérifié sur Terraform 1.15.4 : avecterraform.tfvars posant region = "depuis-tfvars" et terraform.tfvars.json posant "region": "depuis-json", la valeur retenue est depuis-json.La conséquence
Si vous maintenez les deux, la variante.json gagne toujours. Beaucoup de guides les rangent au même niveau : c'est faux.Trois comportements différents
Vérifié sur Terraform 1.15.4 :- dans un fichier
.tfvars:Warning: Value for undeclared variable, le plan réussit ; - via
-var:Error: Value for undeclared variable, le plan échoue ; - via
TF_VAR_: silencieusement ignorée.
Le piège
Une faute de frappe dans un.tfvars (replika au lieu de replicas) ne casse rien : elle produit un avertissement, et la vraie variable reste à son default. On croit avoir changé une valeur, il n'en est rien.Lexical, pas alphabétique
Les*.auto.tfvars sont chargés « in lexical order ». La comparaison porte sur les octets :Z.auto.tfvarspasse avanta.auto.tfvars(majuscules avant minuscules) ;20-calcul.auto.tfvarspasse après10-reseau.auto.tfvars.
Conséquence
En cas de conflit sur une même variable, le fichier le plus loin dans cet ordre gagne. Nommez vos fichiers avec un préfixe numérique cohérent (10-, 20-) pour un ordre prévisible.JSON en ligne de commande
Un.tfvars accepte la syntaxe HCL native :zones = ["a", "b", "c"]
tags = { env = "prod" }
Mais en -var ou TF_VAR_, un type complexe exige du JSON valide, échappé pour le shell :terraform apply -var 'zones=["a","b","c"]'
Recommandation
Réservez les structures aux fichiers, ne passez que des scalaires en-var : c'est plus lisible et moins fragile.Le mode non interactif
Une variable sansdefault qu'aucune source n'alimente déclenche une demande interactive en local. Mais en CI, avec -input=false :terraform plan -input=false
# Error: No value for required variable
La correction
Fournissez toujours les variables requises par un fichier.tfvars, un -var ou un TF_VAR_ dans une chaîne d'automatisation. C'est la cause classique du « ça marche pourtant en local ».Le gitignore ne suffit pas
Gitignorer unsecrets.tfvars empêche de le committer, mais pas la valeur d'atterrir dans terraform.tfstate, en clair. Une valeur fournie par tfvars ou TF_VAR_ finit toujours dans l'état, même si la variable est sensitive (qui ne masque que l'affichage).La vraie protection
- chiffrer le state (backend distant) et restreindre son accès ;
- ou utiliser
ephemeral = true(1.10+), le seul mécanisme qui exclut une valeur du state et du plan.
.tfvars.Pour aller plus loin
Section intitulée « Pour aller plus loin »- Locals Terraform : La valeur calculée dans le code, complément des valeurs fournies par tfvars.
- Le style guide Terraform : Les conventions de nommage et le .gitignore qui protège les tfvars sensibles.
- sensitive : masquer les valeurs : Ce qui arrive à un secret placé dans un tfvars, et ce que sensitive masque vraiment.