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

Déboguer un terraform apply

12 min de lecture

logo terraform

Votre terraform apply échoue avec un message en rouge. Le fichier, la ligne et le type de problème sont indiqués — encore faut-il savoir les lire. Une fois cette compétence acquise, vous trouvez la cause en quelques secondes.

Terraform signale ses erreurs avec précision : fichier, ligne, type de problème, et souvent une suggestion de correction. Les erreurs se répartissent en 4 catégories prévisibles, chacune avec son reflexe de correction. Ce guide les présente avec les messages exacts produits en lab.

Ce que vous allez apprendre :

  • Lire la structure d’un message d’erreur Terraform
  • Diagnostiquer par catégorie : attribut inconnu, référence manquante, type incorrect, erreur runtime
  • Appliquer le workflow validateplanapply pour économiser du temps
  • Provoquer et corriger une erreur réelle dans un lab

Prérequis : avoir suivi le guide Première infrastructure.

Avant de catégoriser les erreurs, voici la structure d’un message d’erreur Terraform :

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

Chaque message comporte :

  • Le type d’erreur en gras (Unsupported argument)
  • La localisation exacte : fichier + numéro de ligne + bloc concerné
  • L’extrait de code fautif
  • L’explication en langage naturel

Commencez toujours par lire la dernière ligne du message — c’est là que se trouve la réponse.

Fenêtre de terminal
terraform validate # 1. Syntaxe et schéma
terraform plan # 2. Logique et dépendances
terraform apply # 3. Runtime

C’est l’erreur la plus courante quand on migre d’une ancienne version du provider à une nouvelle, ou quand on copie-colle du code sans vérifier le schéma.

Erreur réelle capturée en lab :

# bad.tf — erreur volontaire
resource "libvirt_volume" "bad" {
name = "bad.qcow2"
pool = "default"
format = "qcow2" # ← attribut au mauvais endroit
}
Fenêtre de terminal
terraform validate
Error: Unsupported argument
│ on bad.tf line 4, in resource "libvirt_volume" "bad":
│ 4: format = "qcow2"
│ An argument named "format" is not expected here.

Cause : Dans libvirt provider v0.9.7, le format d’un volume se déclare dans target.format.type, pas directement à la racine de la ressource.

Correction :

resource "libvirt_volume" "bad" {
name = "bad.qcow2"
pool = "default"
target = {
format = { type = "qcow2" } # ← emplacement correct
}
}

Réflexe : quand le message dit “not expected here”, consultez le schéma du provider dans la documentation ou avec terraform providers schema.

Fenêtre de terminal
terraform providers schema -json | python3 -m json.tool | grep -A5 '"libvirt_volume"'

Catégorie 2 : référence à une ressource inexistante

Section intitulée « Catégorie 2 : référence à une ressource inexistante »

Terraform résout les références entre ressources lors du validate. Si la ressource référencée n’existe pas, l’erreur est immédiate.

Erreur :

resource "libvirt_domain" "bad" {
devices = {
disks = [{
source = { file = { file = libvirt_volume.missing.path } }
# ↑ "missing" n'est pas déclaré
}]
}
}
Error: Reference to undeclared resource
│ on bad.tf line 4, in resource "libvirt_domain" "bad":
│ 4: source = { file = { file = libvirt_volume.missing.path } }
│ A managed resource "libvirt_volume" "missing" has not been declared
│ in the root module.

Causes fréquentes :

  • Faute de frappe dans le nom (libvirt_volume.disk vs libvirt_volume.dsk)
  • La ressource est dans un autre fichier qui n’a pas encore été créé
  • Le nom a changé lors d’un refactoring

Correction : Vérifiez les noms avec terraform state list si les ressources existent déjà, ou cherchez la déclaration dans vos fichiers .tf.

Terraform est typé. Si une variable attend un number et reçoit une string, l’erreur est détectée à la validation.

Erreur :

resource "libvirt_domain" "bad" {
memory = "512" # ← string au lieu de number
}
Error: Incorrect attribute value type
│ on bad.tf line 3, in resource "libvirt_domain" "bad":
│ 3: memory = "512"
│ Inappropriate value for attribute "memory": a number is required.

Correction : memory = 512 (sans guillemets).

Catégorie 4 : erreurs runtime (après validate et plan)

Section intitulée « Catégorie 4 : erreurs runtime (après validate et plan) »

Certaines erreurs n’apparaissent qu’à terraform apply, quand Terraform interagit réellement avec le provider :

Ressource déjà existante :

Error: Error creating libvirt network: Domain already exists lab14-net

Cela arrive quand la ressource existe dans libvirt mais pas dans le state Terraform (par exemple, après un crash pendant un apply précédent).

Solutions selon la situation :

SituationSolution
La ressource a été créée manuellementterraform import pour l’adopter
Le state a été perduRecréer le state avec terraform import
Doublon involontaireSupprimer la ressource manuellement, puis apply

Permission refusée :

Error: virError(Code=1, Domain=10, Message='authentication failed')

Vérifiez que l’utilisateur a accès à qemu:///system :

Fenêtre de terminal
groups $USER | grep -q libvirt || sudo usermod -aG libvirt $USER

Image de base absente :

Error: error creating libvirt volume: internal error: ...
Cannot access storage file '/chemin/vers/ubuntu-24.04-cloudimg.img'

L’image de base n’existe pas au chemin indiqué. Vérifiez :

Fenêtre de terminal
ls -lh ~/images/ubuntu-24.04-cloudimg.img
  1. Créez un répertoire de test :

    Fenêtre de terminal
    mkdir -p ~/terraform-debug-apply
    cd ~/terraform-debug-apply
  2. Créez versions.tf (correct) puis bad.tf avec une erreur volontaire :

    Fenêtre de terminal
    cat > bad.tf << 'EOF'
    resource "libvirt_volume" "bad" {
    name = "bad.qcow2"
    pool = "default"
    format = "qcow2"
    }
    EOF
  3. Lancez le validate pour voir l’erreur :

    Fenêtre de terminal
    terraform init
    terraform validate
    Error: Unsupported argument
    │ on bad.tf line 4, in resource "libvirt_volume" "bad":
    │ 4: format = "qcow2"
    │ An argument named "format" is not expected here.
  4. Corrigez le fichier :

    Fenêtre de terminal
    cat > bad.tf << 'EOF'
    resource "libvirt_volume" "bad" {
    name = "bad.qcow2"
    pool = "default"
    target = { format = { type = "qcow2" } }
    create = { content = { url = pathexpand("~/images/ubuntu-24.04-cloudimg.img") } }
    }
    EOF
    terraform validate
    # → Success! The configuration is valid.
  5. Supprimez le fichier de test et nettoyez :

    Fenêtre de terminal
    rm bad.tf
CommandeUtilité
terraform validateVérifie syntaxe et schéma (rapide, sans accès provider)
terraform planMontre ce qui sera créé/modifié/détruit
terraform showAffiche l’état actuel des ressources
terraform state listListe toutes les ressources dans le state
TF_LOG=DEBUG terraform applyActive les logs détaillés pour les erreurs obscures
terraform providers schema -jsonAffiche le schéma complet de tous les providers

Pour les erreurs difficiles à diagnostiquer, TF_LOG=DEBUG affiche toutes les requêtes API envoyées au provider :

Fenêtre de terminal
TF_LOG=DEBUG terraform apply 2>&1 | grep -i error
  • Lisez toujours la dernière ligne d’un message d’erreur Terraform — c’est là que se trouve l’explication.
  • L’ordre de diagnostic : validateplanapply.
  • Unsupported argument : l’attribut n’existe pas ou est mal placé dans la hiérarchie.
  • Reference to undeclared resource : faute de frappe ou ressource manquante.
  • Incorrect attribute value type : guillemets en trop ou manquants.
  • Les erreurs runtime apparaissent à apply et concernent l’état réel de l’infrastructure.

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