Terraform — Tests et validation
| Fiche express | |
|---|---|
| Type | Qualité et validation du code Terraform |
| Pipeline type | fmt → validate → lint → security scan → test |
| Outils | terraform fmt/validate/test, tflint, tfsec/checkov
|
| Coût | croissant (statique gratuit → analyse dédiée → exécution réelle) |
| Voir aussi | Terraform — Concepts fondamentaux · Terraform — Modules et variables · Terraform — Intégration CI/CD |
Valider du code Terraform ne se limite pas à lancer terraform apply et regarder ce qui casse. Il existe une hiérarchie d'outils, du contrôle purement syntaxique et gratuit jusqu'au test fonctionnel qui provisionne réellement des ressources. Cette page les présente comme un pipeline de qualité croissante, chaque étage filtrant des erreurs de plus en plus coûteuses à découvrir tard.
Vue d'ensemble du pipeline
<mermaid> flowchart LR
F[terraform fmt
style] --> V[terraform validate
syntaxe + cohérence] V --> L[tflint
bonnes pratiques, erreurs provider] L --> S[tfsec / checkov
sécurité, conformité] S --> T[terraform test
comportement réel]
</mermaid>
Plus on avance vers la droite, plus le contrôle est proche de la réalité (et coûte cher en temps d'exécution, voire en ressources cloud provisionnées) ; plus on reste à gauche, plus le contrôle est rapide, gratuit et exécutable à chaque sauvegarde.
terraform fmt : mise en forme
Réécrit le code selon la convention de style canonique HCL (indentation, alignement des =). Ne détecte aucune erreur logique, seulement le style.
terraform fmt -recursive -check -diff
-check renvoie un code d'erreur sans modifier les fichiers (mode CI) ; -diff affiche les changements proposés. Sans ces options, terraform fmt réécrit directement les fichiers.
terraform validate : validation statique
Vérifie la syntaxe HCL, la cohérence interne (types, arguments requis, références à des ressources/variables existantes) sans contacter les API des providers ni consulter le state.
terraform init -backend=false
terraform validate
Rapide et gratuit, mais limité : validate ne sait pas dire si une AMI existe vraiment, si un quota est atteint, ou si deux ressources vont entrer en conflit au moment de l'apply.
tflint : linting
Va au-delà de la syntaxe : détecte des erreurs spécifiques aux providers (type d'instance inexistant, argument déprécié), des variables déclarées mais jamais utilisées, et applique des règles de style/bonnes pratiques configurables.
tflint --init
tflint --recursive
# .tflint.hcl
plugin "aws" {
enabled = true
version = "0.31.0" # à vérifier selon version
source = "github.com/terraform-linters/tflint-ruleset-aws"
}
rule "terraform_unused_declarations" {
enabled = true
}
tflint fonctionne par plugins par provider (aws, azurerm, google...), à activer selon les providers réellement utilisés dans le projet.
tfsec / checkov : analyse de sécurité
Ces outils analysent statiquement le code HCL pour détecter des configurations à risque avant tout apply : bucket de stockage public, groupe de sécurité ouvert à 0.0.0.0/0, chiffrement au repos désactivé, rôle IAM trop permissif, etc. Ils s'appuient sur des règles prédéfinies (CIS Benchmarks, bonnes pratiques par provider) et peuvent être étendus par des règles personnalisées.
tfsec .
checkov -d .
tfsec est désormais maintenu dans le giron de Trivy (Aqua Security) plutôt qu'en projet séparé (évolution à vérifier selon la période). Checkov (Bridgecrew/Palo Alto) couvre un périmètre plus large que le seul Terraform (Kubernetes, Dockerfile, CloudFormation). Cette page ne détaille pas leurs règles respectives — se référer à leur documentation pour la configuration fine (suppression de règles, seuils de sévérité).
terraform test : tests fonctionnels natifs
Depuis Terraform 1.6 (à vérifier selon version), un framework de test natif permet d'écrire des scénarios dans des fichiers .tftest.hcl, avec des assertions sur le plan ou sur le résultat réel d'un apply.
# tests/network.tftest.hcl
variables {
cidr_block = "10.20.0.0/16"
}
run "plan_creates_expected_cidr" {
command = plan
assert {
condition = aws_vpc.main.cidr_block == var.cidr_block
error_message = "Le CIDR du VPC ne correspond pas à la variable attendue."
}
}
run "apply_creates_vpc" {
command = apply
assert {
condition = aws_vpc.main.id != ""
error_message = "Le VPC n'a pas été créé."
}
}
terraform test
run— un scénario de test, avec ses propres variables et son propre plan/apply.command = plan— teste uniquement le plan (rapide, aucune ressource créée).command = apply— provisionne réellement les ressources dans un environnement de test, puis les détruit automatiquement en fin d'exécution — le plus proche de la réalité, mais aussi le plus lent et le seul de ce pipeline à consommer des ressources cloud facturables.assert— condition booléenne ; échec = message d'erreur explicite, comme pour unevalidationde variable (voir Terraform — Modules et variables).
Où placer chaque étage
- fmt / validate / tflint — à chaque commit ou pré-commit local (hook), et systématiquement en CI dès l'ouverture d'une merge request : rapides, gratuits, aucun effet de bord.
- tfsec / checkov — en CI sur chaque merge request, avant toute revue humaine : un bucket public détecté avant fusion coûte infiniment moins cher qu'après exploitation.
- terraform test — en CI, potentiellement seulement sur les modules critiques ou avant une release, car les scénarios
command = applyprovisionnent réellement des ressources (temps d'exécution, coût, nécessité d'un compte cloud dédié aux tests).
Voir Terraform — Intégration CI/CD pour l'agencement concret de ce pipeline dans une plateforme de CI.