Aller au contenu
English
English
Infrastructure as Code medium

OpenTofu : variables dans backend et sources de modules

10 min de lecture

logo opentofu

L'une des différences les plus pratiques d'OpenTofu est sa capacité a résoudre 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 très concrets : construire une clé de state par environnement, parametrer une version de module a un seul endroit, ou faire varier l'adresse d'un dépôt de modules sans dupliquer toute la configuration.

Cette souplesse n'est pas illimitée. OpenTofu n'accepte que les valeurs qu'il peut calculer avant que le state ne soit disponible. Le modèle mental a garder est donc simple : tout ce qui dépend du state, d'une data source ou d'une provider function arrive trop tard pour tofu init. Cette page vous montre ou la flexibilité est utile, ou elle devient dangereuse et comment la rendre lisible pour l'équipe.

  • 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 référencer pendant l'initialisation ;
  • garder une configuration lisible en local comme en CI.

Dans un dépôt Terraform classique, les équipes finissent souvent par dupliquer beaucoup de texte pour contourner les limites de l'initialisation. Elles copient un même backend avec une seule clé 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 données presentes dans le state ni de fonctions définies 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 dépend d'un provider non encore installe ;
  • interdit : une expression qui a besoin du state courant pour être évaluée.

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 dépend seulement de ces variables ;
  • aucune data source ni aucun provider n'est nécessaire.
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 résolution 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 équipe maintient un mono-repo de modules ou quand plusieurs modules doivent suivre le même 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'intérêt est simple : vous concentrez la version a un seul endroit au lieu de la dupliquer dans plusieurs appels de modules.

Le piège classique consiste a oublier quand OpenTofu doit calculer la valeur.

Exemple a éviter :

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 idée paraît elegante, mais elle echoue pour une raison structurelle : la data source a besoin d'un provider déjà configure et du contexte d'exécution complet, alors que le backend doit être compris avant cette phase.

Le même raisonnement s'applique a tout ce qui dépend du state courant ou de fonctions définies par un provider.

Etape 3 - Garder une configuration lisible en équipe

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

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 dépôt en moteur de templates implicite.

Bonnes pratiques :

  • regrouper les valeurs partagées dans quelques locals explicites ;
  • documenter les variables nécessaires des tofu init ;
  • utiliser des tfvars par environnement ou des variables d'environnement bien nommées ;
  • 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 grâce a des invites interactives. Une CI non interactive, elle, échouera si les variables nécessaires ne sont pas déjà 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 "cassée" alors que le problème vient simplement d'une variable absente a la phase d'initialisation.

Scénarios concrets ou cette différence devient rentable

Section intitulée « Scénarios concrets ou cette différence devient rentable »
ScenarioCe que permet OpenTofu
1 dépôt, plusieurs environnementsconstruire une key de backend par environnement sans dupliquer le bloc
mono-repo de modules internespartager la même ref Git ou la même 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 être fourni des init
SymptômeCause 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 dépend 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 nommés
fuite de credentials backendsecrets passes en CLI ou écrits en durutiliser variables d'environnement ou mécanismes auth du backend
  • OpenTofu peut résoudre 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 ce site gratuitement, sans publicité, sans profilage et sans compte à créer. Un soutien, même symbolique, m'aide à couvrir l'hébergement et à garder ces ressources gratuites. Merci pour votre appui.

Le formulaire ne s'affiche pas ? Ouvrir Ko-fi dans un onglet.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn