
Vous écrivez "${var.env}-${var.vm_name}-${var.region}" à cinq endroits
dans votre configuration. Quand region change, vous devez mettre à jour
cinq lignes — et en oublier une. Ou vous avez une condition complexe
répétée dans plusieurs ressources et plusieurs outputs.
Les locals résolvent ce problème : un local est une expression
intérieure au module, calculée une fois, réutilisée partout via local.nom.
Contrairement aux variables, il ne peut pas être surchargé de l’extérieur —
c’est une valeur dérivée, pas un paramètre. C’est le bon outil pour centraliser
les expressions composites : noms de ressources construits, conditions
d’environnement, maps de tags. Les locals rendent le code plus DRY
(Don’t Repeat Yourself) et plus lisible, car ils permettent de nommer
des expressions autrement anonymes.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Déclarer un local : bloc
locals {}et attributs - Utiliser un local : la référence
local.nomdans les ressources - Expressions courantes : concaténation,
format(),lower(), conditions - Locals vs variables vs outputs : choisir le bon outil
Prérequis
Section intitulée « Prérequis »- Terraform ≥ 1.11 installé (installer Terraform)
- Connaître les variables (variables Terraform)
L’idée derrière les locals
Section intitulée « L’idée derrière les locals »Pensez à une variable locale en programmation classique :
# Plutôt que répéter la même expression 5 foisdisk_name = f"{var.vm_name}.qcow2"
# On la calcule une fois et on la réutiliselabel = f"lab02/{var.vm_name}"tags = {"env": "dev", "label": label} # réutilisé iciresource_name = f"{label}-resource" # et iciLes locals de Terraform font exactement cela : calculer une expression une fois et la réutiliser partout via local.nom.
Déclarer des locals
Section intitulée « Déclarer des locals »Le bloc s’appelle locals (pluriel), mais chaque entrée est un local
accessible via local.nom (singulier) :
locals { disk_name = "${var.vm_name}.qcow2" vm_label = "lab02/${var.vm_name}"}Tous les attributs d’un même bloc locals {} peuvent se référencer
entre eux, à condition de ne pas créer de cycle.
On peut avoir plusieurs blocs locals {} dans un même module :
locals { disk_name = "${var.vm_name}.qcow2" vm_label = "lab02/${var.vm_name}"}
locals { computed_tags = { env = "dev" module = local.vm_label # référence à un local du bloc au-dessus }}Utiliser un local dans une ressource
Section intitulée « Utiliser un local dans une ressource »resource "libvirt_volume" "disk" { name = local.disk_name # résulte en "lab02-vm.qcow2" # ...}
resource "libvirt_domain" "vm" { name = local.vm_label # résulte en "lab02/lab02-vm" # ...}output "vm_label" { description = "Label combiné pool / vm_name via locals" value = local.vm_label}Après apply, l’output montre la valeur calculée :
vm_label = "lab02/lab02-vm"Expressions courantes dans les locals
Section intitulée « Expressions courantes dans les locals »Concaténation avec interpolation
Section intitulée « Concaténation avec interpolation »locals { disk_name = "${var.vm_name}.qcow2"}Fonction format()
Section intitulée « Fonction format() »locals { hostname = format("%s-%03d", var.prefix, var.index) # prefix="web", index=3 → "web-003"}Fonctions de transformation
Section intitulée « Fonctions de transformation »locals { name_lower = lower(var.vm_name) # "Ubuntu-VM" → "ubuntu-vm" name_safe = replace(var.vm_name, "_", "-") # underscores → tirets}Condition ternaire
Section intitulée « Condition ternaire »locals { effective_memory = var.env == "prod" ? 4096 : 512}Construction d’un objet
Section intitulée « Construction d’un objet »locals { common_tags = { project = var.project_name env = var.environment managed = "terraform" }}Locals vs variables vs outputs
Section intitulée « Locals vs variables vs outputs »| Besoin | Outil |
|---|---|
| Valeur fournie de l’extérieur (par CI, tfvars) | variable |
| Valeur calculée, interne au module | local |
| Valeur à exposer après apply | output |
Quand utiliser les locals
Section intitulée « Quand utiliser les locals »Éviter la répétition
Section intitulée « Éviter la répétition »Sans locals, si var.vm_name est utilisé dans 5 ressources avec le suffixe
.qcow2, il faut changer 5 lignes à chaque renommage. Avec un local :
locals { disk_name = "${var.vm_name}.qcow2"}# → le local est mis à jour une seule fois, les 5 ressources suiventCentraliser la logique métier
Section intitulée « Centraliser la logique métier »locals { # Règle : en prod, on double la RAM ; en dev, on prend le défaut effective_memory = var.env == "prod" ? var.memory * 2 : var.memory}Nommer des structures complexes
Section intitulée « Nommer des structures complexes »locals { network_config = [ { network_name = "default" wait_for_lease = false } ]}À retenir
Section intitulée « À retenir »locals {}déclare des valeurs calculées internes, accessibles vialocal.nom- Interpolation, fonctions HCL, conditions — tout est autorisé dans les locals
- Un local ne peut pas être surchargé de l’extérieur (contrairement à une variable)
- Plusieurs blocs
locals {}sont autorisés dans le même module - Les locals peuvent se référencer entre eux (sauf cycle)