Le fichier tfstate

Quand vous créez des infrastructures avec Terraform, le fichier terraform.tfstate est essentiel, c’est lui qui garde à jour l’état de votre déploiement.

Il s’agit d’un fichier texte qui décrit toute l’infrastructure.

A chaque fois que vous appliquez un code Terraform qui modifie un élément, le tfstate évolue en conséquence.

La cohérence entre votre code Terraform et ce qui est déployé dans votre infrastructure est assurée par le tfstate.

Fonctionnement

Etape Action Etat
1 Création de code Terraform Pas de tfstate
2 terraform init Pas de tfstate
3 terraform plan Pas de tfstate
4 terraform apply tfstate qui enregistre l’état
5 Evolution du code Terraform Le tfstate ne bouge pas
6 terraform plan Le tfstate ne bouge pas
7 terraform apply Nouvelle version du tfstate, le n-1 est sauvegardé dans tfstate.backup

Restauration du backup

Le tableau précédent montre que chaque terraform apply crée un backup de l’ancien puis une nouvelle version du tfstate.

En cas de problème avec le fichier tfstate, vous pouvez repartir de la version n-1 en restaurant manuellement le backup :

cp terraform.tfstate.backup terraform.tfstate
terraform init
terraform plan
terraform apply

Backends Terraform

Restaurer le n-1, c’est bien gentil mais si on peut avoir un historique du tfstate, c’est quand même plus sûr.

C’est pourquoi on va préférer le stocker dans un système :

  • Sûr : Des sauvegardes et une reprise d’activité doivent être possibles
  • Versionné : Avoir un historique des states
  • Chiffré : Non lisible pour qu’il ne puisse pas fuiter (le tfstate contient l’état de votre infra)

Utiliser un bucket GCP

Ici, l’exemple sera avec un bucket GCP, mais cela fonctionnerait aussi bien sur AWS avec du S3 ou d’autres backends

On utilise Terraform pour créer un bucket :

# bucket.tf

resource "random_id" "bucket_prefix" {
  byte_length = 8
}

resource "google_storage_bucket" "default" {
  name          = "bucket-tfstate"
  force_destroy = false
  location      = "EUROPE-WEST9"
  storage_class = "STANDARD"
  versioning {
    enabled = true
  }
  depends_on = [
    google_project_iam_member.project
  ]
}

resource "google_project_iam_member" "project" {
  project = var.project_name
  role    = "roles/editor"
  member  = "user:nom@domaine.com"
}

On applique :

terraform plan
terraform apply

Migrer le tfstate

Configuration du backend Terraform :

# backend.tf

terraform {
 backend "gcs" {
   bucket  = google_storage_bucket.default.id
   prefix  = "terraform/state"
 }
}

On applique avec :

terraform init -migrate-state