Aller au contenu
Infrastructure as Code medium
🔐 Alerte sécurité — Incident supply chain Trivy : lire mon analyse de l'attaque

Locals Terraform : valeurs locales calculées

8 min de lecture

logo terraform

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.

  • Déclarer un local : bloc locals {} et attributs
  • Utiliser un local : la référence local.nom dans les ressources
  • Expressions courantes : concaténation, format(), lower(), conditions
  • Locals vs variables vs outputs : choisir le bon outil

Pensez à une variable locale en programmation classique :

# Plutôt que répéter la même expression 5 fois
disk_name = f"{var.vm_name}.qcow2"
# On la calcule une fois et on la réutilise
label = f"lab02/{var.vm_name}"
tags = {"env": "dev", "label": label} # réutilisé ici
resource_name = f"{label}-resource" # et ici

Les locals de Terraform font exactement cela : calculer une expression une fois et la réutiliser partout via local.nom.

Le bloc s’appelle locals (pluriel), mais chaque entrée est un local accessible via local.nom (singulier) :

locals.tf
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
}
}
main.tf
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"
# ...
}
outputs.tf
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"
locals {
disk_name = "${var.vm_name}.qcow2"
}
locals {
hostname = format("%s-%03d", var.prefix, var.index)
# prefix="web", index=3 → "web-003"
}
locals {
name_lower = lower(var.vm_name) # "Ubuntu-VM" → "ubuntu-vm"
name_safe = replace(var.vm_name, "_", "-") # underscores → tirets
}
locals {
effective_memory = var.env == "prod" ? 4096 : 512
}
locals {
common_tags = {
project = var.project_name
env = var.environment
managed = "terraform"
}
}
BesoinOutil
Valeur fournie de l’extérieur (par CI, tfvars)variable
Valeur calculée, interne au modulelocal
Valeur à exposer après applyoutput

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 suivent
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
}
locals {
network_config = [
{
network_name = "default"
wait_for_lease = false
}
]
}
  1. locals {} déclare des valeurs calculées internes, accessibles via local.nom
  2. Interpolation, fonctions HCL, conditions — tout est autorisé dans les locals
  3. Un local ne peut pas être surchargé de l’extérieur (contrairement à une variable)
  4. Plusieurs blocs locals {} sont autorisés dans le même module
  5. Les locals peuvent se référencer entre eux (sauf cycle)

Ce site vous est utile ?

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

Je maintiens +700 guides gratuits, sans pub ni tracing. Aujourd'hui, ce site ne couvre même pas mes frais d'hébergement, d'électricité, de matériel, de logiciels, mais surtout de cafés.

Un soutien régulier, même symbolique, m'aide à garder ces ressources gratuites et à continuer de produire des guides de qualité. Merci pour votre appui.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn