State et workspaces
Le fichier terraform.tfstate : le cœur de Terraform
Terraform ne redéploie pas tout à chaque apply. Il compare ce que tu décris dans ton code
avec ce qui existe réellement dans le cloud. Pour ça, il s'appuie sur un fichier JSON
appelé terraform.tfstate. Ce fichier est critique — sans lui, Terraform ne sait
plus ce qu'il a créé et risque de dupliquer ou de détruire des ressources par erreur.
Ne jamais supprimer ni modifier manuellement terraform.tfstate.
Ce fichier peut contenir des données sensibles (mots de passe, clés API). Il ne doit pas être versionné dans Git en clair.
Ce que contient le state
Le state est un mapping entre tes ressources HCL et les ressources réelles dans le cloud :
- Le type et le nom Terraform (ex.
aws_instance.web) - L'identifiant réel de la ressource chez le provider (ex.
i-0abc123def) - Tous les attributs connus (IP, taille, tags…)
- Les dépendances entre ressources
// Extrait d'un terraform.tfstate
{
"version": 4,
"resources": [
{
"type": "aws_instance",
"name": "web",
"instances": [
{
"attributes": {
"id": "i-0abc123def456",
"instance_type": "t3.micro",
"public_ip": "54.12.34.56"
}
}
]
}
]
}
Problèmes du state local
Par défaut, terraform.tfstate est créé localement dans ton dossier de travail. Ça pose trois problèmes majeurs :
Pas de collaboration
Chaque développeur a son propre state local. Personne ne sait ce que les autres ont appliqué.
Pas de verrouillage
Deux personnes peuvent lancer terraform apply en même temps et corrompre l'infrastructure.
Perte de données
Si le fichier local est effacé ou perdu, Terraform perd la trace de toutes les ressources déployées.
Remote state backends
La solution est de stocker le state dans un backend distant partagé et sécurisé. Les backends les plus utilisés :
- S3 + DynamoDB (AWS) — bucket S3 pour le fichier, table DynamoDB pour le verrou
- Azure Blob Storage — conteneur Azure avec verrouillage natif
- Terraform Cloud / HCP Terraform — solution managée par HashiCorp avec UI, historique et RBAC
- GCS (Google Cloud Storage) — similaire à S3 côté GCP
Configurer un backend S3 avec verrouillage DynamoDB
Pour AWS, la combinaison S3 + DynamoDB est le standard. Le bucket stocke le state,
la table DynamoDB garantit qu'un seul apply tourne à la fois.
# Déclaration du backend S3 avec verrouillage DynamoDB
terraform {
backend "s3" {
bucket = "mon-projet-tfstate"
key = "prod/terraform.tfstate"
region = "eu-west-1"
encrypt = true
# Table DynamoDB pour le verrouillage
dynamodb_table = "terraform-state-lock"
}
}
# La table DynamoDB doit avoir une clé primaire "LockID" (type String)
resource "aws_dynamodb_table" "tf_lock" {
name = "terraform-state-lock"
billing_mode = "PAY_PER_REQUEST"
hash_key = "LockID"
attribute {
name = "LockID"
type = "S"
}
}
Après avoir ajouté ou modifié la configuration du backend, lance terraform init
pour migrer le state existant vers le nouveau backend. Terraform te proposera de copier l'état local automatiquement.
Commandes utiles pour gérer le state
Terraform propose des commandes pour inspecter et manipuler le state sans toucher au fichier JSON :
# Lister toutes les ressources dans le state
terraform state list
# Afficher les détails d'une ressource
terraform state show aws_instance.web
# Renommer une ressource dans le state (sans détruire/recréer)
terraform state mv aws_instance.web aws_instance.frontend
# Retirer une ressource du state (sans la détruire dans le cloud)
terraform state rm aws_instance.old
# Importer une ressource existante dans le state
terraform import aws_instance.imported i-0abc123def456
# Afficher l'état complet formaté
terraform show
terraform state mv est particulièrement utile lors d'un refactoring :
si tu renommes une ressource dans ton code HCL, utilise cette commande pour
mettre à jour le state — sinon Terraform va détruire et recréer la ressource !
Les workspaces Terraform
Les workspaces permettent de gérer plusieurs états indépendants à partir d'une même configuration.
C'est idéal pour avoir des environnements dev, staging et prod
avec le même code, sans dupliquer les fichiers.
Chaque workspace a son propre fichier state. Par défaut, tu es dans le workspace default.
# Voir le workspace actif
terraform workspace show
# Lister tous les workspaces
terraform workspace list
# Créer un nouveau workspace
terraform workspace new staging
# Basculer vers un workspace existant
terraform workspace select prod
# Supprimer un workspace (doit être vide)
terraform workspace delete staging
Dans ton code HCL, tu peux utiliser terraform.workspace pour adapter
la configuration selon l'environnement actif :
# Taille de l'instance selon l'environnement
locals {
instance_type = terraform.workspace == "prod" ? "t3.medium" : "t3.micro"
}
resource "aws_instance" "web" {
ami = "ami-0abcdef1234567890"
instance_type = local.instance_type
tags = {
Name = "web-${terraform.workspace}"
Environment = terraform.workspace
}
}
Avec un backend S3, chaque workspace stocke son state dans un sous-dossier automatique :
env:/staging/prod/terraform.tfstate. Tu n'as rien à configurer manuellement.
Bonnes pratiques
- Ne jamais éditer
terraform.tfstatemanuellement — utilise les commandesterraform state. - Toujours utiliser un remote backend dès que tu travailles en équipe ou en production.
- Activer le chiffrement du state (
encrypt = truesur S3) — il peut contenir des secrets. - Ne jamais committer le state dans Git — ajoute
*.tfstateet*.tfstate.backupà ton.gitignore. - Les workspaces sont pratiques pour des environnements similaires, mais pour des configurations très différentes, préfère des dossiers séparés.
- Utilise
terraform state mvlors de tout refactoring pour éviter des destructions accidentelles.