Terraform — Workspaces et environnements
| Fiche express | |
|---|---|
| Type | Stratégies de gestion multi-environnement |
| Option 1 | workspaces CLI (terraform workspace)
|
| Option 2 | un répertoire par environnement |
| Outil tiers DRY | Terragrunt (hors HashiCorp) |
| Voir aussi | Terraform — Concepts fondamentaux · Terraform — State avancé |
Un même code Terraform doit généralement être appliqué à plusieurs environnements (dev, staging, prod). Deux stratégies dominent : les workspaces natifs (un mécanisme CLI léger) et un répertoire par environnement (plus de duplication, mais plus de sécurité). Cette page détaille les deux, leurs compromis, et situe l'outil tiers Terragrunt.
Workspaces CLI
Un workspace est un espace de nommage à l'intérieur d'un même backend : chaque workspace a son propre fichier de state, mais tous partagent la même configuration backend (mêmes identifiants, même bucket/table) et le même code .tf.
terraform workspace new staging
terraform workspace select staging
terraform workspace list
terraform workspace show
Dans le code, le workspace courant est accessible via terraform.workspace, généralement utilisé pour dériver des noms ou sélectionner des valeurs :
locals {
node_count = {
dev = 1
staging = 2
prod = 5
}
}
resource "vsphere_virtual_machine" "node" {
count = local.node_count[terraform.workspace]
name = "rke2-${terraform.workspace}-${count.index}"
}
Limites
- Un seul backend pour tous les workspaces. Impossible nativement d'isoler dev et prod sur des comptes cloud, des credentials ou des régions différents — c'est structurellement la même connexion backend, seul le state change.
- Risque de confusion humaine. Le workspace actif est un état implicite du terminal (rien dans le nom du répertoire ne l'indique). Un
terraform applylancé par erreur alors qu'on croyait être surdevmais qu'on est resté surprod(workspace mal resélectionné, terminal partagé, script CI qui ne fixe pas explicitement le workspace) est un incident classique. - Pas d'isolement de permissions. Toute personne ayant accès au backend peut, en théorie,
selectn'importe quel workspace — dont la prod — puisque l'accès est au niveau du backend, pas du workspace. - Dérive de code entre environnements mal supportée. Les workspaces supposent un code identique à peu de variables près (
terraform.workspace,lookupsur une map). Dès qu'un environnement a besoin d'une ressource que les autres n'ont pas, le code se remplit de conditionnels (count = terraform.workspace == "prod" ? 1 : 0) qui deviennent vite illisibles.
Les workspaces conviennent bien à des environnements éphémères et interchangeables issus d'un même compte/tenant (ex. un environnement de test par branche de feature), moins à une séparation dev/prod où l'isolement (accès, blast radius, credentials) est un objectif en soi.
Alternative : un répertoire par environnement
Chaque environnement a son propre répertoire, avec son propre appel à terraform init/plan/apply, son propre fichier de configuration backend, et donc son propre state — et potentiellement son propre backend (compte AWS différent, credentials différents).
infra/
├── modules/
│ └── rke2_cluster/ # code partagé, réutilisé par chaque env
├── environments/
│ ├── dev/
│ │ ├── main.tf # module "cluster" { source = "../../modules/rke2_cluster" ... }
│ │ ├── backend.tf # backend dédié dev
│ │ └── terraform.tfvars
│ ├── staging/
│ │ ├── main.tf
│ │ ├── backend.tf
│ │ └── terraform.tfvars
│ └── prod/
│ ├── main.tf
│ ├── backend.tf # backend dédié prod (compte/credentials distincts)
│ └── terraform.tfvars
<mermaid> flowchart TD
M[module rke2_cluster
code partagé] --> D[environments/dev
state + backend dédiés] M --> S[environments/staging
state + backend dédiés] M --> P[environments/prod
state + backend dédiés]
</mermaid>
Le code métier reste factorisé dans un module commun (Terraform — Modules et variables) ; ce qui diffère par environnement (taille, credentials, backend) est isolé dans le répertoire de l'environnement. On ne peut pas se tromper d'environnement par erreur de sélection : le répertoire de travail est l'environnement, visible dans le prompt shell et dans le chemin du cd.
Compromis
- Plus sûr : isolement réel des backends/credentials, pas d'état implicite à sélectionner, blast radius d'une erreur humaine limité à l'environnement où l'on se trouve physiquement.
- Plus de duplication : chaque répertoire répète l'ossature (appel au module, déclaration backend), avec un risque de divergence si on oublie de propager un changement structurel à tous les environnements.
| Workspaces CLI | Un répertoire par environnement | |
|---|---|---|
| Isolation backend/credentials | non (backend unique) | oui (backend par env possible) |
| Risque de confusion | élevé (état implicite) | faible (répertoire explicite) |
| Duplication de code | quasi nulle | ossature répétée par env |
| Cas d'usage typique | envs éphémères, même tenant | dev/staging/prod avec isolement réel |
Terragrunt : DRY multi-environnement
Terragrunt est un outil tiers (Gruntwork, hors HashiCorp) qui s'installe au-dessus de Terraform pour résoudre le problème inverse de la duplication : il génère la configuration backend et les appels de module à partir d'un fichier terragrunt.hcl par environnement, en factorisant tout ce qui est commun (configuration backend, variables partagées) dans un fichier racine hérité par les sous-répertoires. Il orchestre aussi l'exécution sur plusieurs modules dans le bon ordre de dépendance.
Non couvert en détail ici (pas de page dédiée sur ce wiki) — à retenir : Terragrunt cible précisément le compromis « répertoire par environnement, mais sans la duplication », au prix d'un outil et d'une couche de configuration supplémentaires à maîtriser.