Leçon 5 / 6
Leçon 05 · Partie 2 — Gestion de l'état

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
terraform.tfstate (extrait simplifié)
// 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é.

risque de conflits
🔒

Pas de verrouillage

Deux personnes peuvent lancer terraform apply en même temps et corrompre l'infrastructure.

race condition
💥

Perte de données

Si le fichier local est effacé ou perdu, Terraform perd la trace de toutes les ressources déployées.

catastrophique

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.

backend.tf
# 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 :

Terminal — Commandes state
# 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.

Terminal — Workspaces
# 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 :

main.tf — Adapter selon le workspace
# 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

// À retenir
  • Ne jamais éditer terraform.tfstate manuellement — utilise les commandes terraform state.
  • Toujours utiliser un remote backend dès que tu travailles en équipe ou en production.
  • Activer le chiffrement du state (encrypt = true sur S3) — il peut contenir des secrets.
  • Ne jamais committer le state dans Git — ajoute *.tfstate et *.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 mv lors de tout refactoring pour éviter des destructions accidentelles.