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

OpenTofu : variables dans backend et sources de modules

10 min de lecture

logo opentofu

L’une des differences les plus pratiques d’OpenTofu est sa capacite a resoudre certaines variables et certains locals des tofu init, y compris dans la configuration du backend et dans les sources de modules. Cela ouvre des usages tres concrets : construire une cle de state par environnement, parametrer une version de module a un seul endroit, ou faire varier l’adresse d’un depot de modules sans dupliquer toute la configuration.

Cette souplesse n’est pas illimitee. OpenTofu n’accepte que les valeurs qu’il peut calculer avant que le state ne soit disponible. Le modele mental a garder est donc simple : tout ce qui depend du state, d’une data source ou d’une provider function arrive trop tard pour tofu init. Cette page vous montre ou la flexibilite est utile, ou elle devient dangereuse et comment la rendre lisible pour l’equipe.

  • comprendre pourquoi OpenTofu evalue certaines valeurs des tofu init ;
  • parametrer un backend avec variables et locals ;
  • construire des sources de modules ou des versions a partir de variables ;
  • savoir ce qu’il est interdit de referencer pendant l’initialisation ;
  • garder une configuration lisible en local comme en CI.

Dans un depot Terraform classique, les equipes finissent souvent par dupliquer beaucoup de texte pour contourner les limites de l’initialisation. Elles copient un meme backend avec une seule cle qui change, ou plusieurs blocs module differant seulement par un ref, ou encore des wrappers shell qui injectent des valeurs sans laisser de trace lisible dans le code.

OpenTofu permet de remettre un peu d’ordre a cet endroit : on peut centraliser des locals, faire varier des versions et construire des chemins de modules tant que tout reste resolvable avant le chargement du state.

OpenTofu peut utiliser des variables et des locals dans ces zones, mais pas de references a des donnees presentes dans le state ni de fonctions definies par un provider.

En clair :

  • autorise : var.environment, var.bucket_name, local.module_ref ;
  • interdit : data.aws_caller_identity.current.account_id si cela doit servir des init ;
  • interdit : une valeur qui depend d’un provider non encore installe ;
  • interdit : une expression qui a besoin du state courant pour etre evaluee.

Le cas le plus utile est le backend de state. Vous pouvez, par exemple, construire une key de backend par environnement.

variable "environment" {
description = "Target environment name"
type = string
}
variable "state_bucket" {
description = "Bucket storing OpenTofu state"
type = string
}
locals {
state_key = "environments/${var.environment}/network.tfstate"
}
terraform {
backend "s3" {
bucket = var.state_bucket
key = local.state_key
region = "eu-west-3"
}
}

Dans cet exemple, tout est resolvable des tofu init parce que :

  • var.state_bucket et var.environment sont des variables racine ;
  • local.state_key depend seulement de ces variables ;
  • aucune data source ni aucun provider n’est necessaire.
Fenêtre de terminal
tofu init -var-file=environments/dev.tfvars

Exemple de environments/dev.tfvars :

environment = "dev"
state_bucket = "acme-tofu-state"

Etape 2 - Utiliser des locals dans les sources de modules

Section intitulée « Etape 2 - Utiliser des locals dans les sources de modules »

OpenTofu accepte aussi la resolution de variables et locals dans source et version pour les modules.

variable "modules_ref" {
description = "Git ref of the shared module repository"
type = string
default = "v1.20.4"
}
locals {
modules_repo = "git::ssh://git@example.com/platform/tofu-modules.git//aws/vpc"
modules_ref = "?ref=${var.modules_ref}"
}
module "network" {
source = "${local.modules_repo}${local.modules_ref}"
}

Cette approche est utile quand votre equipe maintient un mono-repo de modules ou quand plusieurs modules doivent suivre le meme tag applicatif.

variable "network_module_version" {
description = "Version of the registry module to use"
type = string
default = "1.4.2"
}
module "network" {
source = "acme/network/aws"
version = var.network_module_version
}

L’interet est simple : vous concentrez la version a un seul endroit au lieu de la dupliquer dans plusieurs appels de modules.

Le piege classique consiste a oublier quand OpenTofu doit calculer la valeur.

Exemple a eviter :

data "aws_caller_identity" "current" {}
terraform {
backend "s3" {
bucket = "company-${data.aws_caller_identity.current.account_id}"
key = "network.tfstate"
region = "eu-west-3"
}
}

Cette idee parait elegante, mais elle echoue pour une raison structurelle : la data source a besoin d’un provider deja configure et du contexte d’execution complet, alors que le backend doit etre compris avant cette phase.

Le meme raisonnement s’applique a tout ce qui depend du state courant ou de fonctions definies par un provider.

Etape 3 - Garder une configuration lisible en equipe

Section intitulée « Etape 3 - Garder une configuration lisible en equipe »

La souplesse d’OpenTofu est utile seulement si elle reste lisible. Le bon compromis consiste souvent a centraliser ce qui varie vraiment, sans transformer le depot en moteur de templates implicite.

Bonnes pratiques :

  • regrouper les valeurs partagees dans quelques locals explicites ;
  • documenter les variables necessaires des tofu init ;
  • utiliser des tfvars par environnement ou des variables d’environnement bien nommees ;
  • garder les secrets hors du code et hors des flags shell historises ;
  • ne pas construire des sources de modules illisibles sur trois niveaux de concat.

Etape 4 - Comprendre l’impact sur CI et automation

Section intitulée « Etape 4 - Comprendre l’impact sur CI et automation »

Une configuration locale peut fonctionner grace a des invites interactives. Une CI non interactive, elle, echouera si les variables necessaires ne sont pas deja disponibles.

Exemple d’appel explicite :

Fenêtre de terminal
tofu init -input=false -var-file=environments/prod.tfvars

Le point important est que tofu init a maintenant besoin de certains inputs plus tot. Si vous oubliez ce detail, la CI semblera “cassee” alors que le probleme vient simplement d’une variable absente a la phase d’initialisation.

Scenarios concrets ou cette difference devient rentable

Section intitulée « Scenarios concrets ou cette difference devient rentable »
ScenarioCe que permet OpenTofu
1 depot, plusieurs environnementsconstruire une key de backend par environnement sans dupliquer le bloc
mono-repo de modules internespartager la meme ref Git ou la meme base de source dans plusieurs modules
migration progressivefaire varier la source de modules ou la version depuis une seule variable
CI stricterendre explicite tout ce qui doit etre fourni des init
SymptomeCause probableSolution
tofu init demande une valeur inattenduevariable requise pour backend ou module source non fourniepasser -var ou -var-file des init
backend ou module source refuse l’expressionla valeur depend du state, d’une data source ou d’un providerremplacer par une variable racine ou un local pur
la CI marche en local mais pas en runnersession locale interactive, runner non interactifajouter -input=false et fournir toutes les valeurs explicitement
la source du module devient illisibletrop de concat ou de logique implicitefactoriser avec un petit nombre de locals nommes
fuite de credentials backendsecrets passes en CLI ou ecrits en durutiliser variables d’environnement ou mecanismes auth du backend
  • OpenTofu peut resoudre variables et locals dans des zones lues pendant tofu init.
  • Cette souplesse est utile surtout pour les backends et les sources de modules.
  • Tout doit rester resolvable sans state, sans data source et sans provider function.
  • Une CI non interactive doit recevoir ces valeurs des init, pas seulement des plan ou apply.
  • Le bon usage consiste a rendre la configuration plus lisible, pas a cacher toute la logique dans des concatenations fragiles.

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