Aller au contenu
Infrastructure as Code medium
🔐 Alerte sécurité — Incident supply chain Trivy : lire mon analyse de l'attaque

Le workflow Terraform : init, plan, apply, destroy

11 min de lecture

logo terraform

Vous lancez terraform apply et votre infrastructure change — mais vous ne savez pas exactement ce qui s’est passé. Ou pire : vous avez appliqué sans regarder le plan, et Terraform a détruit une ressource que vous vouliez conserver.

Analogie : le workflow Terraform fonctionne comme la procédure d’un chirurgien. Avant d’opérer, il examine les radios (plan). Il ne dit jamais « j’ai une idée, opérons immédiatement » (apply). Entre la décision et le geste, il y a toujours un moment de vérification. Le plan est cette étape critique : vous lisez exactement ce qui va changer avant d’activer les changements.

En pratique, le cycle quotidien Terraform s’articule autour de 4 commandes : init, plan, apply, destroy. Le core workflow officiel HashiCorp est Write → Plan → Apply ; init est un prérequis d’initialisation et destroy une commande complémentaire. Ce cycle est conçu pour rendre chaque changement d’infrastructure prévisible et contrôlable. Le plan vous montre exactement ce qui va changer avant que quoi que ce soit soit modifié. Comprendre ce que signifient les symboles +, -, ~ dans la sortie du plan est la compétence fondamentale pour utiliser Terraform en production sans mauvaises surprises.

  • Le rôle de chaque commande : init, validate, plan, apply, destroy
  • Lire un plan Terraform : interpréter les +, -, ~ avant d’appliquer
  • Exécuter un cycle complet : de l’initialisation à la destruction sur KVM/libvirt
  • Les pièges du workflow : quand apply échoue à mi-chemin et comment récupérer
  • Terraform ≥ 1.11 installé (guide d’installation)
  • KVM/libvirt opérationnel (pour reproduire l’exemple)
  • Image Ubuntu 24.04 cloud disponible localement

Cycle de travail Terraform : init, validate, plan, apply, destroy

Chaque étape correspond à une phase du cycle de vie d’une infrastructure.

terraform init est toujours la première commande à lancer dans un nouveau projet, ou après l’ajout d’un provider. Elle :

  • Télécharge les providers déclarés dans le bloc required_providers
  • Initialise le backend (local par défaut)
  • Prépare le répertoire .terraform/
Fenêtre de terminal
terraform init

Résultat attendu :

Initializing the backend...
Initializing provider plugins...
- Finding dmacvicar/libvirt versions matching "~> 0.8"...
- Installing dmacvicar/libvirt v0.9.7...
Terraform has been successfully initialized!

terraform validate vérifie que la configuration est syntaxiquement valide et cohérente en interne. Il ne contacte pas les API distantes des providers et ne lit pas le remote state, mais il nécessite un répertoire déjà initialisé (terraform init).

Fenêtre de terminal
terraform validate

Résultat attendu :

Success! The configuration is valid.

En cas d’erreur :

│ Error: Unsupported argument
│ on main.tf line 12, in resource "libvirt_volume" "disk":
│ 12: format = "qcow2"
│ An argument named "format" is not expected here.

Utilisez validate systématiquement avant plan pour détecter les fautes de frappe et les attributs manquants. Si vous ne voulez pas configurer le backend, lancez terraform init -backend=false au préalable.

terraform plan lit l’état courant des objets distants via les providers, compare la configuration au state existant, puis calcule les actions nécessaires pour faire correspondre l’infrastructure à la configuration.

Fenêtre de terminal
terraform plan

L’output liste les ressources à créer (+), modifier (~) ou supprimer (-) :

Terraform will perform the following actions:
# libvirt_volume.disk will be created
+ resource "libvirt_volume" "disk" {
+ name = "lab-01.qcow2"
+ pool = "default"
...
}
Plan: 1 to add, 0 to change, 0 to destroy.

terraform apply exécute les changements affichés par plan. Par défaut, il demande une confirmation interactive.

Fenêtre de terminal
terraform apply

Pour automatiser (scripts, CI/CD) :

Fenêtre de terminal
terraform apply -auto-approve

Résultat attendu :

libvirt_volume.disk: Creating...
libvirt_volume.disk: Creation complete after 1s [id=/var/lib/libvirt/images/lab-01.qcow2]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

Terraform met à jour le fichier terraform.tfstate après chaque apply réussi.

terraform destroy supprime toutes les ressources gérées par le state courant. C’est l’opération inverse d’apply.

Fenêtre de terminal
terraform destroy

Ou sans confirmation :

Fenêtre de terminal
terraform destroy -auto-approve

Voici un exemple inspiré d’une configuration testée avec le provider libvirt 0.9.7 sur KVM.

versions.tf :

terraform {
required_version = ">= 1.11.0"
required_providers {
libvirt = {
source = "dmacvicar/libvirt"
version = "~> 0.8"
}
}
}

main.tf :

provider "libvirt" {
uri = "qemu:///system"
}
resource "libvirt_volume" "disk" {
name = "workflow-demo.qcow2"
pool = "default"
target = {
format = { type = "qcow2" }
}
create = {
content = {
url = "/home/bob/images/ubuntu-24.04-cloudimg.img"
}
}
}
resource "libvirt_domain" "vm" {
name = "workflow-demo"
type = "kvm"
memory = 512
memory_unit = "MiB"
vcpu = 1
os = {
type = "hvm"
type_arch = "x86_64"
type_machine = "q35"
}
devices = {
disks = [
{
source = {
file = { file = libvirt_volume.disk.path }
}
target = {
dev = "vda"
bus = "virtio"
}
}
]
interfaces = [
{
model = { type = "virtio" }
source = { network = { network = "default" } }
}
]
}
}
output "vm_name" {
value = libvirt_domain.vm.name
}

Exécution du cycle complet :

Fenêtre de terminal
terraform init
terraform validate # Success! The configuration is valid.
terraform plan # Plan: 2 to add, 0 to change, 0 to destroy.
terraform apply -auto-approve
virsh list --all # workflow-demo shut off
terraform destroy -auto-approve

Après chaque apply, Terraform écrit un fichier terraform.tfstate qui enregistre la correspondance entre la configuration et les objets d’infrastructure. Lors du prochain plan, il combine plusieurs sources :

Vos fichiers .tf → état souhaité
terraform.tfstate → correspondance connue par Terraform
API provider → état courant observé
Plan → actions proposées

Le state n’est pas « ce qui existe » — c’est la mémoire de Terraform sur les objets qu’il gère. plan s’appuie aussi sur la lecture de l’infrastructure réelle via les providers. Sans le state, Terraform ne peut pas savoir quels objets il gère — il ne faut pas le supprimer manuellement.

Le state est traité en détail dans Gérer le state Terraform.

CommandeRôle
terraform fmtReformate les fichiers .tf selon le style officiel
terraform outputAffiche les valeurs des outputs après apply
terraform showAffiche le state courant de manière lisible
terraform consoleREPL interactif pour tester des expressions
terraform state listListe les ressources dans le state
  • Le workflow est toujours initvalidateplanapply.
  • plan est non destructif : il ne fait qu’afficher les changements.
  • apply modifie l’infrastructure et met à jour le state.
  • destroy supprime toutes les ressources gérées.
  • Le state est le lien entre votre code et l’infrastructure réelle.

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracing. Aujourd'hui, ce site ne couvre même pas mes frais d'hébergement, d'électricité, de matériel, de logiciels, mais surtout de cafés.

Un soutien régulier, même symbolique, m'aide à garder ces ressources gratuites et à continuer de produire des guides de qualité. Merci pour votre appui.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn