Terraform State : Comprendre et Gérer l'État de votre Infrastructure

Comprenez le Terraform State, élément critique de votre infrastructure. State local vs remote, backends S3/Azure/GCS, state locking avec DynamoDB et commandes terraform state.

Quand vous exécutez terraform apply et que des ressources sont créées dans le cloud, une question fondamentale se pose : comment Terraform sait-il ce qu'il a déjà créé ? Comment fait-il la différence entre une ressource à créer, à modifier ou à supprimer ? La réponse tient en deux mots : le state (état). Le fichier state est le cerveau de Terraform. Sans lui, Terraform serait incapable de gérer votre infrastructure. Pourtant, c'est aussi l'un des aspects les plus mal compris et les plus dangereux si on le gère mal.

Dans cet article, nous allons démystifier le state Terraform. Vous comprendrez ce qu'il contient, pourquoi il est critique, comment le stocker de manière sécurisée avec un backend distant, et comment manipuler le state avec les commandes avancées. C'est un sujet incontournable pour quiconque veut utiliser Terraform en production ou en équipe.

Gestion du Terraform State

Diagramme - Terraform State : Comprendre et Gérer l'État de votre Infrastructure

Qu'est-ce que le Terraform State ?

Le rôle du state

Le state est un fichier JSON qui contient la cartographie complète entre vos ressources déclarées dans le code Terraform (les fichiers .tf) et les ressources réelles qui existent chez votre provider cloud. Il joue trois rôles essentiels :

  • Mapping : il associe chaque bloc resource de votre code à un identifiant réel dans le cloud (par exemple, aws_instance.webi-0abc123def456).
  • Cache des métadonnées : il stocke les attributs des ressources (adresses IP, ARN, tags, etc.) pour accélérer les opérations et calculer les dépendances.
  • Détection des changements : lors d'un terraform plan, Terraform compare le code souhaité, le state actuel et l'état réel dans le cloud pour déterminer les actions nécessaires.

Ce processus de comparaison tripartite est au cœur du fonctionnement de Terraform :

┌──────────────────┐     ┌──────────────────┐     ┌──────────────────┐
│   Code Terraform │     │   State File     │     │   Cloud Réel     │
│   (fichiers .tf) │     │ (terraform.tfstate)│    │   (API AWS)      │
│                  │     │                  │     │                  │
│  Ce que vous     │     │  Ce que Terraform│     │  Ce qui existe   │
│  VOULEZ          │     │  CONNAÎT         │     │  VRAIMENT        │
└────────┬─────────┘     └────────┬─────────┘     └────────┬─────────┘
         │                       │                         │
         └───────────┬───────────┘                         │
                     │                                     │
              terraform plan ──────────── refresh ─────────┘
                     │
              ┌──────┴──────┐
              │  Plan des   │
              │  changements│
              └─────────────┘

Le fichier terraform.tfstate

Par défaut, Terraform stocke le state dans un fichier local nommé terraform.tfstate à la racine de votre projet. Examinons à quoi il ressemble :

# Après un terraform apply, le fichier est créé automatiquement
ls -la terraform.tfstate

# C'est un fichier JSON lisible
cat terraform.tfstate | python3 -m json.tool | head -50

Voici un extrait simplifié du contenu :

{
  "version": 4,
  "terraform_version": "1.5.7",
  "serial": 12,
  "lineage": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "outputs": {
    "vpc_id": {
      "value": "vpc-0abc123def456789",
      "type": "string"
    },
    "instance_public_ip": {
      "value": "52.47.123.45",
      "type": "string"
    }
  },
  "resources": [
    {
      "mode": "managed",
      "type": "aws_vpc",
      "name": "main",
      "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]",
      "instances": [
        {
          "schema_version": 1,
          "attributes": {
            "id": "vpc-0abc123def456789",
            "cidr_block": "10.0.0.0/16",
            "enable_dns_hostnames": true,
            "enable_dns_support": true,
            "tags": {
              "Name": "terraform-demo-dev-vpc",
              "Project": "terraform-demo",
              "Environment": "dev",
              "ManagedBy": "terraform"
            }
          }
        }
      ]
    },
    {
      "mode": "managed",
      "type": "aws_instance",
      "name": "web",
      "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]",
      "instances": [
        {
          "schema_version": 1,
          "attributes": {
            "id": "i-0abc123def456789",
            "ami": "ami-0xyz987654321",
            "instance_type": "t3.micro",
            "public_ip": "52.47.123.45",
            "private_ip": "10.0.1.42",
            "subnet_id": "vpc-subnet-0abc123",
            "tags": {
              "Name": "terraform-demo-dev-web"
            }
          },
          "dependencies": [
            "aws_key_pair.main",
            "aws_security_group.web",
            "aws_subnet.public",
            "data.aws_ami.amazon_linux"
          ]
        }
      ]
    }
  ]
}

Les éléments clés de ce fichier sont :

  • version : la version du format du state (actuellement 4).
  • serial : un compteur incrémenté à chaque modification, utilisé pour le locking.
  • lineage : un identifiant unique de cette chaîne de state, pour éviter les mélanges accidentels.
  • outputs : les valeurs des outputs déclarés.
  • resources : la liste complète des ressources avec tous leurs attributs et dépendances.

Pourquoi le state est critique

Le state est littéralement la source de vérité de Terraform. Voici les scénarios catastrophiques liés à une mauvaise gestion du state :

  • State supprimé : Terraform ne sait plus rien de vos ressources existantes. Il tentera de tout recréer, échouera sur les conflits de noms, et vous vous retrouverez avec des ressources orphelines impossibles à gérer.
  • State corrompu : des incohérences entre le state et la réalité provoquent des erreurs imprévisibles lors des plans et des apply.
  • State désynchronisé : si quelqu'un modifie une ressource manuellement dans la console AWS, le state ne le sait pas. Le prochain plan pourrait écraser ces modifications.
  • State partagé sans locking : deux personnes exécutent terraform apply simultanément, le state est corrompu par les écritures concurrentes.

State Local vs State Remote

Les limites du state local

Par défaut, le state est stocké localement dans le fichier terraform.tfstate. Cela fonctionne parfaitement pour un développeur seul sur un projet personnel, mais pose de sérieux problèmes dès que vous travaillez en équipe :

  • Pas de partage : chaque développeur a sa propre copie du state. Qui a la version à jour ?
  • Pas de locking : rien n'empêche deux personnes d'exécuter terraform apply en même temps.
  • Risque de perte : un disque dur qui lâche, un répertoire supprimé par erreur, et votre state est perdu.
  • Sécurité : le fichier est en clair sur le disque, accessible à quiconque a accès à la machine.

Le state remote : la solution

Un backend remote stocke le state sur un service distant partagé. Terraform supporte nativement de nombreux backends :

  • AWS S3 (avec DynamoDB pour le locking) — le plus populaire
  • Azure Blob Storage (avec locking natif)
  • Google Cloud Storage (avec locking natif)
  • HashiCorp Consul
  • Terraform Cloud / HCP Terraform
  • PostgreSQL, HTTP, et d'autres

Les avantages du state remote sont :

  • Partage : toute l'équipe travaille avec le même state.
  • Locking : un verrou empêche les exécutions concurrentes.
  • Durabilité : stocké sur un service cloud redondant, pas de risque de perte.
  • Chiffrement : possibilité de chiffrer le state au repos.
  • Versioning : historique des versions du state pour revenir en arrière si nécessaire.

Configurer un Backend S3 avec DynamoDB

La combinaison S3 + DynamoDB est le backend le plus utilisé pour les projets AWS. S3 stocke le fichier state, et DynamoDB fournit le mécanisme de locking pour empêcher les modifications concurrentes.

Étape 1 : Créer les ressources du backend

Avant de configurer le backend, il faut créer le bucket S3 et la table DynamoDB. C'est le classique problème de l'œuf et de la poule : on utilise souvent un projet Terraform séparé (ou la console AWS) pour créer ces ressources :

# backend-setup/main.tf
# Ce fichier est appliqué UNE SEULE FOIS pour créer les ressources du backend

provider "aws" {
  region = "eu-west-3"
}

# Bucket S3 pour stocker le state
resource "aws_s3_bucket" "terraform_state" {
  bucket = "mon-entreprise-terraform-state"

  # Empêcher la suppression accidentelle
  lifecycle {
    prevent_destroy = true
  }

  tags = {
    Name      = "Terraform State"
    ManagedBy = "terraform"
    Purpose   = "terraform-state-backend"
  }
}

# Activer le versioning pour l'historique du state
resource "aws_s3_bucket_versioning" "terraform_state" {
  bucket = aws_s3_bucket.terraform_state.id

  versioning_configuration {
    status = "Enabled"
  }
}

# Chiffrement côté serveur
resource "aws_s3_bucket_server_side_encryption_configuration" "terraform_state" {
  bucket = aws_s3_bucket.terraform_state.id

  rule {
    apply_server_side_encryption_by_default {
      sse_algorithm = "aws:kms"
    }
    bucket_key_enabled = true
  }
}

# Bloquer tout accès public
resource "aws_s3_bucket_public_access_block" "terraform_state" {
  bucket = aws_s3_bucket.terraform_state.id

  block_public_acls       = true
  block_public_policy     = true
  ignore_public_acls      = true
  restrict_public_buckets = true
}

# Table DynamoDB pour le state locking
resource "aws_dynamodb_table" "terraform_locks" {
  name         = "terraform-state-locks"
  billing_mode = "PAY_PER_REQUEST"
  hash_key     = "LockID"

  attribute {
    name = "LockID"
    type = "S"
  }

  tags = {
    Name      = "Terraform State Locks"
    ManagedBy = "terraform"
    Purpose   = "terraform-state-locking"
  }
}

output "s3_bucket_name" {
  value = aws_s3_bucket.terraform_state.bucket
}

output "dynamodb_table_name" {
  value = aws_dynamodb_table.terraform_locks.name
}

Quelques points importants sur cette configuration :

  • lifecycle prevent_destroy : empêche la suppression accidentelle du bucket via terraform destroy. C'est une protection essentielle.
  • Versioning activé : chaque modification du state crée une nouvelle version. Vous pouvez ainsi revenir à une version antérieure en cas de problème.
  • Chiffrement KMS : le state est chiffré au repos avec AWS KMS, crucial car il contient des données sensibles.
  • PAY_PER_REQUEST : le mode de facturation DynamoDB à la demande évite de provisionner de la capacité inutile (le locking génère très peu de requêtes).
  • LockID : la clé de partition utilisée par Terraform pour le mécanisme de verrouillage.

Étape 2 : Configurer le backend dans votre projet

Une fois les ressources créées, configurez le backend dans votre projet Terraform principal :

# versions.tf
terraform {
  required_version = ">= 1.3.0"

  # Configuration du backend S3
  backend "s3" {
    bucket         = "mon-entreprise-terraform-state"
    key            = "projects/mon-projet/terraform.tfstate"
    region         = "eu-west-3"
    dynamodb_table = "terraform-state-locks"
    encrypt        = true
  }

  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

Les paramètres du backend :

  • bucket : le nom du bucket S3 créé à l'étape précédente.
  • key : le chemin du fichier state dans le bucket. Utilisez une convention de nommage cohérente pour organiser les states de vos différents projets.
  • region : la région du bucket S3.
  • dynamodb_table : la table DynamoDB pour le locking.
  • encrypt : active le chiffrement côté serveur.

Étape 3 : Migrer le state local vers le backend

Si vous avez déjà un state local et que vous ajoutez un backend remote, Terraform vous proposera de migrer automatiquement :

terraform init

# Terraform détecte le changement de backend :
# Initializing the backend...
# Do you want to copy existing state to the new backend?
#   Enter a value: yes

# Successfully configured the backend "s3"!

Après la migration, votre fichier terraform.tfstate local est vidé (il ne contient plus qu'une référence au backend) et le state réel se trouve dans S3.

Organisation des states par projet

Pour une organisation avec plusieurs projets et environnements, adoptez une convention de nommage structurée dans le bucket S3 :

mon-entreprise-terraform-state/
├── projects/
│   ├── application-web/
│   │   ├── dev/terraform.tfstate
│   │   ├── staging/terraform.tfstate
│   │   └── prod/terraform.tfstate
│   ├── data-platform/
│   │   ├── dev/terraform.tfstate
│   │   └── prod/terraform.tfstate
│   └── infrastructure-commune/
│       └── terraform.tfstate
└── modules/
    └── ...
# Pour chaque environnement, ajustez la clé :
backend "s3" {
  bucket         = "mon-entreprise-terraform-state"
  key            = "projects/application-web/dev/terraform.tfstate"
  region         = "eu-west-3"
  dynamodb_table = "terraform-state-locks"
  encrypt        = true
}

Le State Locking en Détail

Le state locking est un mécanisme qui empêche deux opérations Terraform de modifier le state simultanément. Sans locking, des écritures concurrentes pourraient corrompre le state et laisser votre infrastructure dans un état incohérent.

Comment ça fonctionne

Quand vous exécutez terraform plan ou terraform apply, voici ce qui se passe en coulisses :

  1. Terraform tente d'acquérir un verrou en créant une entrée dans la table DynamoDB.
  2. Si le verrou est disponible, l'opération continue normalement.
  3. Si le verrou est déjà pris par une autre opération, Terraform affiche un message d'erreur et refuse de continuer.
  4. À la fin de l'opération (succès ou échec), Terraform libère le verrou en supprimant l'entrée DynamoDB.
# Exemple de message quand le state est verrouillé
$ terraform apply
╷
│ Error: Error acquiring the state lock
│
│ Error message: ConditionalCheckFailedException: The conditional request failed
│ Lock Info:
│   ID:        a1b2c3d4-e5f6-7890
│   Path:      mon-entreprise-terraform-state/projects/mon-projet/terraform.tfstate
│   Operation: OperationTypeApply
│   Who:       alice@laptop
│   Version:   1.5.7
│   Created:   2023-01-15 14:30:00.000000 UTC
│   Info:
│
│ Terraform acquires a state lock to protect the state from being
│ written by multiple users at the same time. Please resolve the
│ issue above and try again.
╵

Forcer le déverrouillage

Si un processus Terraform se termine anormalement (crash, perte de connexion, Ctrl+C brutal), le verrou peut rester bloqué. Dans ce cas, utilisez force-unlock :

# Déverrouiller le state (utiliser l'ID affiché dans le message d'erreur)
terraform force-unlock a1b2c3d4-e5f6-7890

Backends pour les Autres Clouds

Azure Blob Storage

terraform {
  backend "azurerm" {
    resource_group_name  = "rg-terraform-state"
    storage_account_name = "tfstatemonentreprise"
    container_name       = "terraform-state"
    key                  = "projects/mon-projet/terraform.tfstate"
  }
}

Azure Blob Storage fournit le locking nativement via les leases Blob, sans nécessiter de service supplémentaire comme DynamoDB.

Google Cloud Storage

terraform {
  backend "gcs" {
    bucket = "mon-entreprise-terraform-state"
    prefix = "projects/mon-projet"
  }
}

GCS offre également le locking natif. Le prefix définit le répertoire dans le bucket.

HashiCorp Consul

terraform {
  backend "consul" {
    address = "consul.example.com:8500"
    scheme  = "https"
    path    = "terraform/mon-projet"
    lock    = true
  }
}

Consul est particulièrement adapté si vous l'utilisez déjà dans votre stack HashiCorp (Vault, Nomad, etc.).

Commandes terraform state

Terraform fournit un ensemble de sous-commandes terraform state pour inspecter et manipuler le state. Ces commandes sont indispensables pour la maintenance et le débogage.

terraform state list

Affiche la liste de toutes les ressources présentes dans le state :

$ terraform state list

aws_instance.web
aws_internet_gateway.main
aws_key_pair.main
aws_route_table.public
aws_route_table_association.public[0]
aws_route_table_association.public[1]
aws_s3_bucket.assets
aws_security_group.web
aws_subnet.public[0]
aws_subnet.public[1]
aws_vpc.main
data.aws_ami.amazon_linux
data.aws_caller_identity.current

# Filtrer par type de ressource
$ terraform state list aws_subnet.*
aws_subnet.public[0]
aws_subnet.public[1]

terraform state show

Affiche les détails complets d'une ressource spécifique dans le state :

$ terraform state show aws_instance.web

# aws_instance.web:
resource "aws_instance" "web" {
    ami                          = "ami-0abc123def456"
    arn                          = "arn:aws:ec2:eu-west-3:123456789012:instance/i-0abc123"
    availability_zone            = "eu-west-3a"
    id                           = "i-0abc123def456"
    instance_state               = "running"
    instance_type                = "t3.micro"
    key_name                     = "terraform-demo-dev-key"
    private_ip                   = "10.0.1.42"
    public_ip                    = "52.47.123.45"
    subnet_id                    = "subnet-0abc123"
    vpc_security_group_ids       = [
        "sg-0abc123",
    ]
    tags                         = {
        "Environment" = "dev"
        "Name"        = "terraform-demo-dev-web"
        "Project"     = "terraform-demo"
    }
    # ... (attributs supplémentaires)
}

terraform state mv

Renomme une ressource dans le state sans la recréer. C'est indispensable quand vous refactorisez votre code Terraform :

# Renommer une ressource
terraform state mv aws_instance.web aws_instance.application

# Déplacer dans un module
terraform state mv aws_instance.web module.compute.aws_instance.web

# Renommer un module
terraform state mv module.old_name module.new_name

Sans state mv, le renommage d'une ressource dans le code HCL ferait croire à Terraform qu'il faut supprimer l'ancienne et en créer une nouvelle, ce qui entraînerait une interruption de service.

terraform state rm

Supprime une ressource du state sans la supprimer dans le cloud. La ressource devient "orpheline" — elle existe toujours mais n'est plus gérée par Terraform :

# Retirer une ressource du state
terraform state rm aws_instance.web

# La ressource existe toujours dans AWS mais Terraform ne la connaît plus

# Retirer toutes les instances d'un module
terraform state rm module.old_module

Les cas d'usage typiques :

  • Transférer la gestion d'une ressource à un autre projet Terraform.
  • Arrêter de gérer une ressource avec Terraform (passage en gestion manuelle).
  • Corriger un state corrompu en retirant une entrée problématique.

terraform state pull et push

Ces commandes permettent de récupérer et de pousser manuellement le state vers le backend :

# Télécharger le state remote en local (stdout)
terraform state pull > state_backup.json

# Examiner le state
cat state_backup.json | python3 -m json.tool

# Pousser un state local vers le backend remote (DANGEREUX)
terraform state push state_backup.json

terraform import

Bien que ce ne soit pas techniquement une sous-commande de terraform state, terraform import est étroitement lié au state. Il permet d'importer une ressource existante (créée manuellement ou par un autre outil) dans le state Terraform :

# Importer un VPC existant
terraform import aws_vpc.main vpc-0abc123def456

# Importer une instance EC2
terraform import aws_instance.web i-0abc123def456

# Importer un bucket S3
terraform import aws_s3_bucket.assets mon-bucket-existant

Après l'import, vous devez écrire le code HCL correspondant à la ressource importée. Terraform 1.5+ introduit la possibilité de générer la configuration automatiquement avec les blocs import :

# Terraform 1.5+ : import déclaratif
import {
  to = aws_vpc.main
  id = "vpc-0abc123def456"
}

# Puis générer la configuration :
# terraform plan -generate-config-out=generated.tf

State et Travail en Équipe

Bonnes pratiques pour le travail collaboratif

Travailler à plusieurs sur la même infrastructure Terraform nécessite de la discipline. Voici les règles essentielles :

  1. Toujours utiliser un backend remote avec locking activé. C'est non négociable.
  2. Ne jamais modifier le state manuellement. Utilisez les commandes terraform state.
  3. Exécuter terraform plan avant apply et relire la sortie attentivement.
  4. Utiliser des workspaces ou des répertoires séparés pour les différents environnements.
  5. Intégrer Terraform dans un pipeline CI/CD pour centraliser les exécutions.

Pipeline CI/CD typique

Dans un workflow professionnel, les exécutions Terraform sont centralisées dans un pipeline CI/CD :

# Exemple de pipeline GitLab CI
stages:
  - validate
  - plan
  - apply

validate:
  stage: validate
  script:
    - terraform init -backend=false
    - terraform validate
    - terraform fmt -check

plan:
  stage: plan
  script:
    - terraform init
    - terraform plan -out=tfplan
  artifacts:
    paths:
      - tfplan

apply:
  stage: apply
  script:
    - terraform init
    - terraform apply tfplan
  when: manual  # Approbation manuelle requise
  only:
    - main

Ce workflow garantit que :

  • Le code est validé avant toute exécution.
  • Le plan est sauvegardé et peut être relu avant l'apply.
  • L'apply nécessite une approbation manuelle.
  • Seule la branche main peut déclencher un apply.

Sécurité du State

Le fichier state contient potentiellement des données sensibles : mots de passe de bases de données, clés privées TLS, tokens API, adresses IP internes. Sa protection est donc primordiale.

Mesures de sécurité essentielles

  • Chiffrement au repos : activez le chiffrement côté serveur sur votre backend (S3 avec KMS, Azure avec encryption, etc.).
  • Chiffrement en transit : utilisez toujours HTTPS pour communiquer avec le backend.
  • Contrôle d'accès strict : limitez l'accès au bucket S3 / Blob Storage aux seuls utilisateurs et rôles IAM qui en ont besoin.
  • Audit des accès : activez AWS CloudTrail ou équivalent pour tracer qui accède au state.
  • Pas de commit du state dans Git : c'est la règle la plus importante.

Le fichier .gitignore indispensable

Votre .gitignore doit impérativement exclure les fichiers state et les autres fichiers sensibles de Terraform :

# .gitignore pour un projet Terraform

# State files - CRITIQUE
*.tfstate
*.tfstate.*
*.tfstate.backup

# Répertoire de travail Terraform
.terraform/
.terraform.lock.hcl

# Variables avec des valeurs sensibles
*.tfvars
!example.tfvars

# Plans sauvegardés
*.tfplan
*.plan

# Clés SSH générées
*.pem
*.key

# Fichiers de crash
crash.log
crash.*.log

# Override files (utilisés pour les surcharges locales)
override.tf
override.tf.json
*_override.tf
*_override.tf.json

Remarquez la ligne !example.tfvars : elle réinclut un fichier d'exemple qui montre la structure attendue des variables, sans contenir de vraies valeurs. C'est une bonne pratique pour documenter quelles variables sont nécessaires :

# example.tfvars - Fichier d'exemple (commité dans Git)
# Copiez ce fichier en terraform.tfvars et remplissez les valeurs

project_name = "mon-projet"
environment  = "dev"
region       = "eu-west-3"

# Valeurs sensibles - à fournir via TF_VAR_ ou un gestionnaire de secrets
# db_password = "..."
# api_key     = "..."

Politique IAM restrictive pour le state

# Politique IAM pour accéder au state
resource "aws_iam_policy" "terraform_state_access" {
  name        = "terraform-state-access"
  description = "Accès au bucket S3 et à la table DynamoDB du state Terraform"

  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Sid    = "S3StateAccess"
        Effect = "Allow"
        Action = [
          "s3:GetObject",
          "s3:PutObject",
          "s3:DeleteObject",
          "s3:ListBucket"
        ]
        Resource = [
          "arn:aws:s3:::mon-entreprise-terraform-state",
          "arn:aws:s3:::mon-entreprise-terraform-state/*"
        ]
      },
      {
        Sid    = "DynamoDBLockAccess"
        Effect = "Allow"
        Action = [
          "dynamodb:GetItem",
          "dynamodb:PutItem",
          "dynamodb:DeleteItem"
        ]
        Resource = "arn:aws:dynamodb:eu-west-3:*:table/terraform-state-locks"
      }
    ]
  })
}

Dépannage et Récupération du State

Le state est désynchronisé

Si des modifications manuelles ont été faites dans le cloud, utilisez terraform refresh (ou terraform apply -refresh-only depuis Terraform 1.x) pour resynchroniser le state avec la réalité :

# Resynchroniser le state avec le cloud (lecture seule)
terraform apply -refresh-only

# Terraform affiche les différences détectées et demande confirmation

Récupérer une version antérieure du state

Grâce au versioning S3, vous pouvez récupérer une version précédente du state :

# Lister les versions du state dans S3
aws s3api list-object-versions \
  --bucket mon-entreprise-terraform-state \
  --prefix projects/mon-projet/terraform.tfstate

# Récupérer une version spécifique
aws s3api get-object \
  --bucket mon-entreprise-terraform-state \
  --key projects/mon-projet/terraform.tfstate \
  --version-id "abc123xyz" \
  state_backup.json

# Restaurer cette version (après vérification !)
terraform state push state_backup.json

Recréer un state perdu avec import

Dans le pire des cas, si le state est totalement perdu, vous pouvez reconstruire le state en important chaque ressource :

# Importer chaque ressource existante une par une
terraform import aws_vpc.main vpc-0abc123
terraform import aws_subnet.public[0] subnet-0abc123
terraform import aws_subnet.public[1] subnet-0def456
terraform import aws_security_group.web sg-0abc123
terraform import aws_instance.web i-0abc123

# Vérifier que le plan ne montre aucun changement
terraform plan
# Objectif : "No changes. Your infrastructure matches the configuration."

C'est un processus long et fastidieux, d'où l'importance de ne jamais perdre son state.

Conclusion

Le state Terraform est un composant critique que vous ne pouvez pas ignorer. Résumons les points essentiels :

  • Le state est la source de vérité de Terraform — il mappe votre code aux ressources réelles dans le cloud.
  • Le state local convient pour l'apprentissage, mais en production, utilisez toujours un backend remote avec locking.
  • La combinaison S3 + DynamoDB est le standard pour les projets AWS : stockage durable, chiffré et verrouillé.
  • Les commandes terraform state (list, show, mv, rm, pull, push) sont vos outils de maintenance quotidiens.
  • La sécurité du state est non négociable : chiffrement, contrôle d'accès strict, et surtout jamais de commit dans Git.
  • Le versioning du backend est votre filet de sécurité pour récupérer d'un état corrompu.

Avec une bonne gestion du state, vous êtes prêt à utiliser Terraform en équipe et en production. Dans les prochains articles, nous explorerons les modules Terraform pour structurer votre code en composants réutilisables, et les workspaces pour gérer plusieurs environnements avec la même base de code. La maîtrise de l'Infrastructure as Code continue !

Vous vous êtes abonné avec succès à CodeClan
Parfait ! Ensuite, complétez le paiement pour obtenir un accès complet à tout le contenu premium.
Erreur ! Impossible de s'inscrire. Lien invalide.
Bienvenue ! Vous vous êtes connecté avec succès.
Erreur ! Impossible de se connecter. Veuillez réessayer.
Succès ! Votre compte est entièrement activé, vous avez maintenant accès à tout le contenu.
Erreur ! Le paiement Stripe a échoué.
Succès ! Vos informations de facturation sont mises à jour.
Erreur ! La mise à jour des informations de facturation a échoué.