
terraform test exécute des assertions sur votre configuration, crée les ressources, vérifie les résultats, puis détruit tout automatiquement. C’est le framework de test natif de Terraform (depuis la version 1.6). Il permet de valider qu’un module produit les outputs attendus, que les valeurs par défaut sont correctes, et que les paramètres personnalisés sont bien appliqués — le tout sans laisser de ressources orphelines.
Prérequis : Terraform >= 1.6. Les exemples de ce site restent alignés sur la base projet Terraform >= 1.11, mais terraform test lui-même est bien disponible depuis la version 1.6. Avoir lu Créer un module Terraform et Variables et outputs.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Écrire des fichiers de test
.tftest.hclavec des assertions - Exécuter les tests avec
terraform test - Distinguer les tests
plan(validation) etapply(intégration) - Filtrer les tests par fichier
- Lire les résultats d’échec pour diagnostiquer un problème
Structure d’un projet avec tests
Section intitulée « Structure d’un projet avec tests »Les fichiers de test vont dans un dossier tests/ à la racine du projet :
mon-projet/├── modules/│ └── reseau/│ ├── versions.tf│ ├── variables.tf│ ├── main.tf│ └── outputs.tf├── versions.tf├── variables.tf├── main.tf├── outputs.tf└── tests/ ├── valeurs_par_defaut.tftest.hcl ├── parametres_custom.tftest.hcl └── validation_plan.tftest.hclConfiguration racine requise
Section intitulée « Configuration racine requise »Les fichiers .tftest.hcl ne testent pas un module isolé dans le vide. Ils s’exécutent dans le projet racine où vous lancez terraform test. Cela signifie que la configuration racine doit déjà appeler le module à tester et exposer les outputs utilisés dans les assertions.
Dans ce guide, les tests supposent cette configuration minimale :
module "reseau" { source = "./modules/reseau" nom = "test-reseau"
cidr = { adresse = "10.10.90.0" masque = "255.255.255.0" }
plage_dhcp = { debut = "10.10.90.10" fin = "10.10.90.50" }}output "reseau_nom" { value = module.reseau.nom}
output "reseau_config" { value = module.reseau.configuration}Sans ces outputs racine, une assertion comme output.reseau_nom échouera immédiatement avec une erreur du type Reference to undefined output.
Anatomie d’un fichier de test
Section intitulée « Anatomie d’un fichier de test »Un fichier .tftest.hcl contient un ou plusieurs blocs run :
run "nom_du_test" { command = apply # ↑ apply (crée les ressources) ou plan (vérifie sans créer)
assert { condition = output.reseau_nom == "test-reseau" # ↑ expression booléenne qui doit être true error_message = "Le nom du réseau devrait être 'test-reseau'" # ↑ message affiché si la condition est false }
assert { condition = output.reseau_config.mode == "nat" error_message = "Le mode par défaut devrait être 'nat'" }}| Élément | Rôle |
|---|---|
run "..." | Bloc de test nommé |
command | apply (intégration réelle) ou plan (validation sans déploiement) |
assert | Assertion à vérifier — plusieurs assertions par bloc run possibles |
condition | Expression booléenne — true = test passé |
error_message | Message affiché si le test échoue |
Écrire un test de valeurs par défaut
Section intitulée « Écrire un test de valeurs par défaut »Le premier test vérifie que le module fonctionne correctement avec les valeurs par défaut de la configuration racine :
run "deployer_avec_defaults" { command = apply
assert { condition = output.reseau_nom == "test-reseau" error_message = "Le nom du réseau devrait être 'test-reseau'" }
assert { condition = output.reseau_config.mode == "nat" error_message = "Le mode par défaut devrait être 'nat'" }
assert { condition = output.reseau_config.dns_actif == true error_message = "Le DNS devrait être activé par défaut" }
assert { condition = output.reseau_config.adresse == "10.10.90.0" error_message = "L'adresse devrait être '10.10.90.0'" }}Ce test utilise command = apply : Terraform crée réellement la ressource, vérifie les outputs, puis détruit automatiquement la ressource à la fin.
Écrire un test avec des paramètres personnalisés
Section intitulée « Écrire un test avec des paramètres personnalisés »Le bloc variables au niveau du fichier permet de surcharger les valeurs :
variables { nom = "custom-test" cidr = { adresse = "10.10.91.0" masque = "255.255.255.0" } plage_dhcp = { debut = "10.10.91.10" fin = "10.10.91.50" } activer_dns = false mode_forward = "route"}
run "deployer_avec_custom" { command = apply
assert { condition = output.reseau_nom == "custom-test" error_message = "Le nom devrait être 'custom-test'" }
assert { condition = output.reseau_config.mode == "route" error_message = "Le mode devrait être 'route'" }
assert { condition = output.reseau_config.dns_actif == false error_message = "Le DNS devrait être désactivé" }}Le bloc variables s’applique à tous les blocs run du fichier.
Écrire un test de validation (plan only)
Section intitulée « Écrire un test de validation (plan only) »Avec command = plan, Terraform vérifie les outputs prévus sans créer de ressource :
run "verifier_plan" { command = plan
assert { condition = output.reseau_nom == "test-reseau" error_message = "Le nom prévu devrait être 'test-reseau'" }}Les tests plan sont plus rapides et ne nécessitent pas d’accès à l’infrastructure. Ils sont utiles pour valider la logique de la configuration sans effets de bord.
Exécuter les tests
Section intitulée « Exécuter les tests »Tous les tests
Section intitulée « Tous les tests »$ terraform test
tests/parametres_custom.tftest.hcl... in progress run "deployer_avec_custom"... passtests/parametres_custom.tftest.hcl... tearing downtests/parametres_custom.tftest.hcl... passtests/valeurs_par_defaut.tftest.hcl... in progress run "deployer_avec_defaults"... passtests/valeurs_par_defaut.tftest.hcl... tearing downtests/valeurs_par_defaut.tftest.hcl... passtests/validation_plan.tftest.hcl... in progress run "verifier_plan"... passtests/validation_plan.tftest.hcl... tearing downtests/validation_plan.tftest.hcl... pass
Success! 3 passed, 0 failed.Chaque fichier passe par trois phases :
- in progress — exécution du
planouapply - pass/fail — résultat des assertions
- tearing down — destruction automatique des ressources
Filtrer par fichier
Section intitulée « Filtrer par fichier »Pour n’exécuter qu’un seul fichier de test :
$ terraform test -filter=tests/validation_plan.tftest.hcl
run "verifier_plan"... passtests/validation_plan.tftest.hcl... tearing downtests/validation_plan.tftest.hcl... pass
Success! 1 passed, 0 failed.Lire un test en échec
Section intitulée « Lire un test en échec »Quand une assertion échoue, Terraform affiche un diff entre la valeur réelle et la valeur attendue :
run "test_qui_echoue"... fail╷│ Error: Test assertion failed││ on tests/test_echec.tftest.hcl line 6, in run "test_qui_echoue":│ 6: condition = output.reseau_nom == "mauvais-nom"│ ├────────────────│ │ Diff:│ │ --- actual│ │ +++ expected│ │ - "test-reseau"│ │ + "mauvais-nom"││ Le nom devrait être 'mauvais-nom' (assertion volontairement fausse)╵
Failure! 2 passed, 1 failed.Le diff indique clairement :
- actual (
-) : la valeur produite par Terraform - expected (
+) : la valeur attendue dans l’assertion
plan vs apply : quand utiliser quoi
Section intitulée « plan vs apply : quand utiliser quoi »| Mode | Crée des ressources | Vitesse | Cas d’usage |
|---|---|---|---|
command = plan | Non | Rapide | Validation de la logique, valeurs calculées, types |
command = apply | Oui (puis détruit) | Plus lent | Test d’intégration, vérifier le comportement réel |
La recommandation est d’utiliser les deux :
planpour les tests rapides de validation (CI/CD, feedback immédiat)applypour les tests d’intégration avant un merge ou une release
Bonnes pratiques pour les tests
Section intitulée « Bonnes pratiques pour les tests »| Pratique | Pourquoi |
|---|---|
| Un fichier par scénario | Lisibilité et filtrage facile |
Noms de blocs run descriptifs | Diagnostic rapide en cas d’échec |
| Tester les defaults séparément | Détecter les régressions sur les valeurs par défaut |
| Tester les paramètres custom | Vérifier que les variables sont bien transmises |
Utiliser plan quand possible | Tests plus rapides, pas besoin d’infrastructure |
| Intégrer dans la CI | Exécuter terraform test automatiquement à chaque push |
Dépannage
Section intitulée « Dépannage »| Symptôme | Cause probable | Solution |
|---|---|---|
command not found: test | Version Terraform < 1.6 | Mettre à jour Terraform (>= 1.6) |
No test files found | Fichiers pas dans tests/ ou mauvaise extension | Vérifier l’extension .tftest.hcl et l’emplacement |
Test apply échoue mais plan passe | Problème côté provider/infrastructure | Vérifier la connectivité et les permissions |
| Ressources non détruites après un crash | Interruption brutale pendant le test | terraform destroy manuellement dans le dossier d’état |
output.X non accessible | L’output n’est pas déclaré dans la config racine | Ajouter l’output dans outputs.tf de la racine |
À retenir
Section intitulée « À retenir »terraform testexécute des fichiers.tftest.hcldepuis le dossiertests/- Chaque bloc
runcontient une ou plusieurs assertions (assert) command = planvalide sans créer ;command = applyteste en conditions réelles- Le teardown automatique détruit les ressources après chaque test — même en cas d’échec
- Le bloc
variablespermet de surcharger les valeurs pour tester différents scénarios - L’option
-filterpermet d’exécuter un fichier de test spécifique - Le diff dans les erreurs indique clairement la valeur réelle vs attendue