Aller au contenu
Infrastructure as Code medium

Fichiers tfvars Terraform : précédence et pièges

15 min de lecture

logo terraform

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.

  • Le chargement automatique des terraform.tfvars et *.auto.tfvars
  • L'ordre de précédence exact (avec tfvars.json et 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

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.

terraform.tfvars
region = "eu-west-3"
replicas = 3
tags = { 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 :

RangSource
1le default du bloc variable
2la variable d'environnement TF_VAR_<nom>
3le fichier terraform.tfvars
4le fichier terraform.tfvars.json
5les *.auto.tfvars (et .json), en ordre lexical
6les 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.

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, le plan réussit ;
  • via -var : une erreur, le plan échoue ;
  • via TF_VAR_ : silencieusement ignorée, aucun message.
Fenêtre de terminal
# faute de frappe dans terraform.tfvars : replika au lieu de replicas
terraform plan
Warning: Value for undeclared variable

Les 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 :

Fenêtre de terminal
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 :

Fenêtre de terminal
terraform plan -input=false
# Error: No value for required variable

C'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.

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é.

-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 :

Fenêtre de terminal
terraform apply -var-file="production.auto.tfvars"
terraform apply -var-file="base.tfvars" -var-file="prod.tfvars"

Ces symptômes viennent presque tous de la précédence ou d'une variable non déclarée.

SymptômeCauseSolution
Une valeur de .tfvars semble ignoréeUn *.auto.tfvars ou un -var la surchargeVérifier la précédence ; -var gagne toujours
Warning: Value for undeclared variableUne variable d'un .tfvars sans bloc variableCorriger le nom, ou déclarer la variable
Error: Value for undeclared variableLa même faute, mais via -varCorriger le nom passé en ligne de commande
No value for required variable en CI-input=false et aucune source pour une variable requiseFournir la valeur par fichier, -var ou TF_VAR_
Un secret apparaît dans le statetfvars et TF_VAR_ finissent en clair dans l'étatChiffrer le state, ou utiliser ephemeral
  1. Sont auto-chargés : terraform.tfvars, terraform.tfvars.json, et les *.auto.tfvars(.json). Un autre nom passe par -var-file.
  2. Précédence : default < TF_VAR_ < terraform.tfvars < terraform.tfvars.json < *.auto.tfvars (ordre lexical) < -var / HCP.
  3. Variable non déclarée : warning en fichier, erreur en -var, ignorée en TF_VAR_. Une faute de frappe dans un .tfvars ne casse rien.
  4. Les types complexes en -var exigent une syntaxe JSON.
  5. -input=false échoue sur une variable requise sans valeur.
  6. Une valeur de .tfvars ou TF_VAR_ finit dans le state ; seul ephemeral l'en exclut.

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.

Ce site vous est utile ?

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

Je maintiens +700 guides gratuits, sans pub ni tracking. 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