
Votre configuration Terraform contient des valeurs en dur : nom de la VM, taille mémoire, chemin de l’image. Pour changer un paramètre, vous devez modifier le code. Si deux projets partagent la même structure mais des valeurs différentes, vous dupliquez tout le fichier.
Les variables résolvent ce problème en séparant la logique (le code HCL) des valeurs (les paramètres). Vous écrivez le code une seule fois dans main.tf, puis vous changez les valeurs dans terraform.tfvars sans toucher à la logique. Les locals centralisent les calculs réutilisés, et les outputs exposent les résultats après chaque apply.
Ce que vous allez apprendre :
- Déclarer des variables typées avec validation dans
variables.tf - Calculer des valeurs dérivées avec
locals - Exposer des résultats avec
outputpour l’affichage et l’intermodule - Surcharger les valeurs avec
terraform.tfvars,TF_VAR_*et-var
Prérequis : avoir suivi le guide Première infrastructure.
Pourquoi des variables ?
Section intitulée « Pourquoi des variables ? »Sans variable :
resource "libvirt_domain" "vm" { name = "lab02-vm" # en dur — impossible de réutiliser memory = 512}Avec variable :
resource "libvirt_domain" "vm" { name = var.vm_name # paramétrable memory = var.memory}La séparation est nette : la logique reste dans main.tf, les valeurs vont dans terraform.tfvars.
La structure du lab
Section intitulée « La structure du lab »Le projet se compose de six fichiers, chacun avec un rôle précis :
mon-projet/├── versions.tf # Provider et version Terraform├── variables.tf # Déclarations des variables d'entrée├── locals.tf # Valeurs calculées (ne changent pas entre environnements)├── main.tf # Ressources libvirt├── outputs.tf # Ce que Terraform affiche après apply└── terraform.tfvars # Valeurs concrètes (surchargent les defaults)Cette organisation est une convention très répandue dans les projets Terraform. Elle n’est pas obligatoire — tout pourrait tenir dans un seul fichier — mais elle rend la navigation immédiate.
Déclarer une variable
Section intitulée « Déclarer une variable »Dans variables.tf, chaque bloc variable {} déclare une entrée possible :
variable "vm_name" { description = "Nom de la VM libvirt" type = string default = "lab02-vm"
validation { condition = can(regex("^[a-z0-9-]+$", var.vm_name)) error_message = "Le nom de VM ne peut contenir que des minuscules, des chiffres et des tirets." }}
variable "memory" { description = "RAM allouée en MiB" type = number default = 512
validation { condition = var.memory >= 256 && var.memory <= 16384 error_message = "La mémoire doit être comprise entre 256 et 16384 MiB." }}
variable "vcpu" { description = "Nombre de vCPUs" type = number default = 1}
variable "image_path" { description = "Chemin vers l'image cloud de base" type = string default = "~/images/ubuntu-24.04-cloudimg.img"}
variable "pool" { description = "Pool libvirt cible" type = string default = "default"}Anatomie d’une déclaration de variable :
| Champ | Obligatoire | Rôle |
|---|---|---|
description | Recommandé | Documente l’usage dans terraform console et les outils |
type | Recommandé | Valide que la valeur fournie est du bon type |
default | Facultatif | Si absent, Terraform demandera la valeur interactivement |
validation | Facultatif | Ajoute des contraintes métier vérifiées avant le plan |
Les locals : valeurs calculées
Section intitulée « Les locals : valeurs calculées »Les locals sont différents des variables : ils ne reçoivent pas de valeur de l’extérieur, ils calculent quelque chose à partir d’autres valeurs.
locals { disk_name = "${var.vm_name}.qcow2" vm_label = "lab02/${var.vm_name}"}Utilisez locals quand :
- Une valeur est calculée à partir d’une variable mais n’a pas de sens à surcharger de l’extérieur.
- La même expression apparaît à plusieurs endroits dans
main.tf.
Utiliser les variables dans main.tf
Section intitulée « Utiliser les variables dans main.tf »Dans main.tf, accédez aux variables avec le préfixe var. et aux locals avec local. :
resource "libvirt_volume" "disk" { name = local.disk_name # "lab02-vm.qcow2" calculé par locals pool = var.pool # valeur de la variable target = { format = { type = "qcow2" } } create = { content = { url = pathexpand(var.image_path) } }}
resource "libvirt_domain" "vm" { name = var.vm_name # "lab02-vm" par défaut type = "kvm" memory = var.memory # 512 MiB par défaut memory_unit = "MiB" vcpu = var.vcpu
os = { type = "hvm", type_arch = "x86_64", type_machine = "q35" }
devices = { disks = [{ source = { file = { file = libvirt_volume.disk.path } } target = { dev = "vda", bus = "virtio" } }] interfaces = [{ model = { type = "virtio" } source = { network = { network = "default" } } }] }}Déclarer des outputs
Section intitulée « Déclarer des outputs »Les outputs affichent des informations utiles après le apply et peuvent être utilisés par d’autres modules Terraform :
output "vm_name" { description = "Nom de la VM créée" value = libvirt_domain.vm.name}
output "vm_memory" { description = "RAM allouée en MiB" value = libvirt_domain.vm.memory}
output "disk_path" { description = "Chemin du volume disque créé" value = libvirt_volume.disk.path}
output "vm_label" { description = "Label calculé par locals" value = local.vm_label}Les outputs ne servent pas seulement à l’affichage. Quand un module appelle un autre module, les outputs sont le seul moyen de récupérer des valeurs calculées.
Appliquer et surcharger les valeurs
Section intitulée « Appliquer et surcharger les valeurs »-
Appliquez avec les valeurs par défaut :
Fenêtre de terminal cd ~/terraform-variables-outputsterraform initterraform apply -auto-approveTerraform affiche les outputs à la fin :
Apply complete! Resources: 2 added, 0 changed, 0 destroyed.Outputs:disk_path = "/var/lib/libvirt/images/lab02-vm.qcow2"vm_label = "lab02/lab02-vm"vm_memory = 512vm_name = "lab02-vm" -
Surchargez une variable en ligne de commande :
Fenêtre de terminal terraform apply -var="vm_name=mon-test" -var="memory=1024" -auto-approveTerraform crée une nouvelle VM nommée
mon-testavec 1 Go de RAM. Les variables non mentionnées gardent leur valeur par défaut. -
Utilisez un fichier
terraform.tfvarspour des valeurs permanentes :terraform.tfvars vm_name = "lab02-custom"memory = 1024vcpu = 2Terraform charge automatiquement
terraform.tfvarss’il existe dans le répertoire courant. Ne mettez pas ce fichier dans git s’il contient des données sensibles (tokens, mots de passe). -
Détruisez le lab :
Fenêtre de terminal terraform destroy -auto-approve
L’ordre de priorité des valeurs
Section intitulée « L’ordre de priorité des valeurs »Quand une variable est définie à plusieurs endroits, Terraform applique cet ordre (du moins prioritaire au plus prioritaire) :
default dans variables.tf < fichier .tfvars < variable d'environnement TF_VAR_nom < flag -var en ligne de commandeUn -var=... écrase tout le reste. C’est utile pour les scripts CI/CD qui injectent des valeurs sans modifier les fichiers.
Ré-afficher les outputs
Section intitulée « Ré-afficher les outputs »Après un apply, vous pouvez ré-afficher les outputs sans refaire un plan :
terraform outputterraform output vm_name # valeur spécifiqueterraform output -json # format JSON pour les scriptsÀ retenir
Section intitulée « À retenir »- Les variables (
variable {}) externalisent les valeurs configurables. Les defaults rendent les variables optionnelles. - Les locals (
locals {}) calculent des valeurs dérivées réutilisables dansmain.tf. - Les outputs (
output {}) exposent des informations après chaqueapply. terraform.tfvarscentralise les valeurs d’un environnement sans modifier le code.- L’ordre de priorité :
default<.tfvars<TF_VAR_*<-var.