Jusqu’ici, toutes les valeurs étaient en dur dans le code. Ça fonctionne pour un lab, mais en entreprise tu as des environnements dev, staging, prod — tous avec des configs différentes. Les variables transforment ton code Terraform en template réutilisable. C’est ce qui sépare un prototype d’une vraie infrastructure.
Déclarer des variables d’entrée
Une variable d’entrée injecte une valeur dans ta configuration sans modifier le code. Tu la déclares avec le bloc variable et tu la références avec var.nom.
variable "server_name" {
description = "Nom du serveur à créer"
type = string
default = "web-1"
}
variable "server_count" {
description = "Nombre de serveurs"
type = number
default = 1
}
variable "enable_backups" {
description = "Activer les backups automatiques"
type = bool
default = false
}
Trois arguments essentiels : description (obligatoire moralement), type (détecte les erreurs tôt) et default (rend la variable optionnelle).
💡 Règle : si une variable n’a pas de default, Terraform la demandera interactivement au plan/apply. En CI/CD, ça bloque le pipeline. Définis toujours un default ou fournis la valeur explicitement.
Types complexes
HCL va bien au-delà des scalaires. Les types complexes te permettent de structurer tes données proprement :
# Liste — collection ordonnée d'un même type
variable "allowed_ports" {
type = list(number)
default = [22, 80, 443]
}
# Map — paires clé-valeur
variable "tags" {
type = map(string)
default = {
Environment = "dev"
Team = "platform"
}
}
# Object — structure typée avec des champs nommés
variable "database" {
type = object({
engine = string
size = number
multi_az = bool
})
default = {
engine = "postgres"
size = 50
multi_az = false
}
}
La différence clé : map a des clés dynamiques du même type, object a des champs fixes avec des types différents. Utilise object quand la structure est connue à l’avance, map quand les clés varient.
Validation des valeurs
Depuis Terraform 0.13, tu peux valider les variables en amont — le plan échoue immédiatement avec un message clair au lieu de planter à mi-chemin :
variable "environment" {
type = string
description = "Environnement cible"
validation {
condition = contains(["dev", "staging", "prod"], var.environment)
error_message = "L'environnement doit être dev, staging ou prod."
}
}
variable "server_count" {
type = number
validation {
condition = var.server_count > 0 && var.server_count <= 20
error_message = "Le nombre de serveurs doit être entre 1 et 20."
}
}
🔥 En entreprise, c’est indispensable. Sans validation, un server_count = 500 passe au plan et crée 500 serveurs avant que quelqu’un ne s’en rende compte.
Variables sensibles
Pour les secrets, marque la variable comme sensitive — Terraform masque la valeur dans les logs et le plan :
variable "db_password" {
type = string
sensitive = true
}
⚠️ Attention : sensitive masque l’affichage, mais ne chiffre rien dans le state. Pour protéger le state, utilise un backend distant chiffré (S3 avec KMS, Terraform Cloud).
Assigner des valeurs aux variables
Plusieurs méthodes, par ordre de priorité croissante (la dernière gagne) :
defaultdans la déclarationterraform.tfvars— chargé automatiquement*.auto.tfvars— chargé automatiquement (ordre alphabétique)-var-file="prod.tfvars"— fichier explicite-var="region=eu-west-1"— en ligne de commandeTF_VAR_region=eu-west-1— variable d’environnement
La convention la plus courante : un fichier .tfvars par environnement.
# prod.tfvars — puis : terraform apply -var-file="prod.tfvars"
environment = "prod"
server_count = 3
server_name = "api-prod"
enable_backups = true
tags = {
Environment = "production"
CostCenter = "engineering"
}
⚠️ Ne commite jamais un .tfvars contenant des secrets. Utilise des variables d’environnement (TF_VAR_db_password) ou un gestionnaire de secrets (Vault, AWS Secrets Manager).
Les outputs : exposer des valeurs
Les outputs affichent des informations après apply et permettent de partager des données entre modules.
output "server_ip" {
description = "IP publique du serveur"
value = hcloud_server.web.ipv4_address
}
output "server_url" {
description = "URL d'accès au serveur"
value = "https://${hcloud_server.web.ipv4_address}"
}
output "db_endpoint" {
description = "Endpoint de la base"
value = hcloud_server.db.ipv4_address
sensitive = true
}
Après apply, Terraform affiche les outputs non sensibles. Tu peux les requêter avec terraform output ou terraform output -raw server_ip pour le scripting. Dans un contexte multi-modules, les outputs d’un module enfant sont accessibles via module.nom_module.nom_output.
Les locals : variables internes calculées
Les locals sont des valeurs calculées en interne — des alias que personne ne peut surcharger de l’extérieur. Parfait pour éviter la répétition et clarifier le code.
locals {
name_prefix = "${var.project}-${var.environment}"
is_prod = var.environment == "prod"
common_tags = {
Project = var.project
Environment = var.environment
ManagedBy = "terraform"
}
}
resource "hcloud_server" "web" {
name = "${local.name_prefix}-web"
server_type = local.is_prod ? "cx32" : "cx22"
image = "ubuntu-24.04"
labels = local.common_tags
}
Quand utiliser quoi ?
variable= paramètre d’entrée fourni par l’appelant (configurable)locals= valeur dérivée, calculée en interne (non configurable)output= valeur de sortie, exposée à l’extérieur
💡 Règle pratique : si tu écris la même expression plus de deux fois, crée un local. Si la valeur doit être paramétrable, c’est une variable.
Cas entreprise : multi-environnements avec les mêmes fichiers
Une équipe gère 3 environnements (dev, staging, prod) pour une application SaaS. Sans variables, ils avaient 3 dossiers avec du code quasi-identique — un cauchemar de maintenance.
Avec les variables, un seul jeu de fichiers .tf et 3 fichiers .tfvars :
infra/
├── main.tf
├── variables.tf
├── outputs.tf
├── dev.tfvars # 1 serveur cx22, pas de backup
├── staging.tfvars # 2 serveurs cx22, backup activé
└── prod.tfvars # 3 serveurs cx32, backup + monitoring
Le code est identique, seules les valeurs changent. Un changement d’architecture se fait une seule fois et se propage automatiquement. Les code reviews sont plus simples — on revoit du code, pas des valeurs.
🎯 Le gain : quand ils ajoutent un 4e environnement (sandbox), c’est un nouveau fichier .tfvars de 10 lignes. Pas 500 lignes de .tf dupliquées.
Les pièges classiques
⚠️ Type any — Évite type = any. Ça accepte tout et détecte les erreurs trop tard. Sois explicite : string, number, list(string), object({...}).
⚠️ Default mutable — Si tu définis un default = [] pour une liste, Terraform crée une nouvelle liste vide à chaque apply. Ce n’est pas un piège fonctionnel, mais garde-le en tête pour les count conditionnels.
⚠️ Ordre de priorité — -var en CLI écrase tout, y compris le .tfvars. En debug, c’est pratique. En CI/CD, c’est une source de bugs si quelqu’un oublie qu’un -var traîne dans le pipeline.
⚠️ Outputs sensibles dans les logs CI — Même avec sensitive = true, un terraform output -json expose tout. Protège les logs de ta CI.
Résumé
Les variables sont le mécanisme de paramétrage fondamental de Terraform :
variable= entrées paramétrables avec type, validation et default- Types =
string,number,bool,list,map,object,tuple - Assignation =
terraform.tfvars,-var-file,-var,TF_VAR_* output= exposer des valeurs après apply (affichage + inter-modules)locals= valeurs calculées internes, non surchargeablessensitive= masquer les secrets dans les logs (pas dans le state)
Dans le prochain chapitre, on approfondit les locals, les outputs avancés et les expressions conditionnelles — pour écrire du Terraform vraiment élégant.
🖥️ Pratique sur ton propre serveur
Pour suivre Terraform en conditions réelles, tu as besoin d'un VPS. DigitalOcean offre 200$ de crédit gratuit pour démarrer.
Contenu réservé aux abonnés
Ce chapitre fait partie de la formation complète. Abonne-toi pour débloquer tous les contenus.
Débloquer pour 29 CHF/moisLe chapitre 1 de chaque formation est gratuit.
Série pas encore débloquée
Termine la série prérequise d'abord pour accéder à ce contenu.
Aller à la série prérequiseSérie : Terraform
3 / 6Sur cette page
Articles liés
Init, Plan, Apply : le workflow Terraform
Maîtrise le workflow Terraform complet : init, plan, apply, destroy. Puis découvre les resources, data sources, le state et la structure de projet.
Pourquoi l'IaC ? Introduction à Terraform
Découvre l'Infrastructure as Code, installe Terraform, apprends la syntaxe HCL, les providers et réalise ton premier déploiement sur Hetzner.
Locals, outputs et expressions
Boucles count et for_each, blocs dynamiques, expressions conditionnelles et fonctions built-in Terraform pour du code DRY.