Meta description : Tests Terraform 2026 : framework natif
terraform test(.tftest.hcl), asserts surplan, puis policies OPA/Conftest sur le plan JSON. Lab FR pratique enca-central-1.À la fin de ce tutoriel, vous saurez poser une pyramide de tests IaC (fmt/validate/tflint →
terraform test→ Conftest), écrire des runs.tftest.hclaveccommand = planetassert, exporter un plan JSON pour OPA/Conftest (tags, région, ACL), et brancher le tout en CI GitHub Actions — sans clés AWS en dur et sans coût cloud pour les tests unitaires.Niveau : Intermédiaire · Temps estimé : 50–65 min · Versions cibles : Terraform ≥ 1.9 (framework depuis 1.6 ; mocks depuis 1.7) · AWS provider ~> 5.0 · Conftest / OPA (vérifier release) · Dernière vérification : 2026-09-11
Slug proposé :
wow-terraform-tests-2026· Série : WOW / Terraform · Focus SEO :terraform test(secondaires :terraform opa,conftest terraform)Statut : PUBLISH GO — prêt WordPress sous
/tutoriels/(parent 5463) — Maître feu vert
Prérequis
- [ ] Découvrir Terraform (IaC, providers, state)
- [ ] Installer Terraform (≥ 1.9) —
terraform versionOK - [ ] Workflow init → plan → apply
- [ ] Modules Terraform — bases
- [ ] State distant S3 + lock (notion ; non obligatoire pour ce lab
plan) - [ ] Terminal Linux / macOS / WSL ; profil AWS optionnel (
AWS_PROFILE/ SSO) — jamais de clés dans le HCL - [ ] Coût estimé : 0 € pour
terraform testencommand = plan; Conftest local gratuit ; Region lab :ca-central-1
Angle DevOps Elastic Hayway : pratique, pas de métriques inventées, pas de hype marketplace.
Ce que nous allons construire
Lab Tests Terraform 2026 (WOW) — ca-central-1
├── module/ versions.tf + main.tf (S3 tags / naming)
├── tests/ *.tftest.hcl (run plan + assert)
├── policy/ deny.rego (Conftest / OPA)
├── terraform plan -out → show -json → conftest test
├── .github/workflows/ terraform-test.yml (sketch)
└── Erreurs + FAQ + Quiz + maillage série TF / WOW
(Schéma Excalidraw / draw.io — alt : « Pyramide tests IaC 2026 : fmt/validate/tflint → terraform test → OPA/Conftest sur plan JSON ».)
Image mise en avant (placeholder) : assets/web/devopelastichayway/cover-wow-terraform-tests-2026-1200x630.webp
Pourquoi tester l’IaC en 2026
Un terraform apply qui passe en CI n’est pas une preuve de qualité : il prouve seulement que le plan a été appliqué. En 2026, la pyramide DEH :
| Couche | Outil | Rôle | Coût cloud |
|---|---|---|---|
| Syntaxe / style | terraform fmt · validate · TFLint |
Catch rapide avant review | 0 |
| Unitaire module | terraform test (.tftest.hcl) |
Asserts sur plan/apply, variables, outputs | 0 si command = plan |
| Policy-as-code | OPA / Conftest sur plan JSON | Deny tags manquants, région, ACL publique | 0 |
| Intégration (optionnel) | Terratest (Go) | Smoke post-apply | €€ — hors scope lab |
Terratest reste utile pour l’intégration lourde. Ici : natif HashiCorp + Conftest. Voir Conftest CI et Policy-as-Code OPA.
HowTo — Étape 1 : Module lab minimal (S3, ca-central-1)
Objectif : bucket S3 avec tags et nom préfixé. Les tests unitaires n’appliquent pas si command = plan.
mkdir -p ~/lab-tf-tests-2026/{module,tests,policy}
cd ~/lab-tf-tests-2026
export AWS_PROFILE=lab
export AWS_DEFAULT_REGION=ca-central-1
module/versions.tf :
terraform {
required_version = ">= 1.9.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = var.aws_region
# Auth : AWS_PROFILE / SSO / env — jamais de clés en dur
}
module/variables.tf + extrait main.tf :
variable "aws_region" {
type = string
default = "ca-central-1"
}
variable "bucket_prefix" { type = string }
variable "tags" { type = map(string) }
variable "environment" {
type = string
validation {
condition = contains(["dev", "staging", "prod"], var.environment)
error_message = "environment doit être dev, staging ou prod."
}
}
resource "aws_s3_bucket" "lab" {
bucket = "${var.bucket_prefix}-${var.aws_region}"
tags = var.tags
}
Gardez le module petit : exercer terraform test et Conftest, pas toute la landing S3.
HowTo — Étape 2 : Fichiers tests/*.tftest.hcl
Terraform découvre .tftest.hcl et .tftest.json (souvent sous tests/). Chaque fichier contient des blocs run. Par défaut, command = apply — en lab DEH, forcez command = plan.
tests/bucket_plan.tftest.hcl :
variables {
aws_region = "ca-central-1"
bucket_prefix = "deh-lab-tf-tests"
environment = "dev"
tags = {
Project = "deh-wow"
Environment = "dev"
Owner = "platform"
}
}
run "plan_bucket_naming_and_tags" {
command = plan
assert {
condition = aws_s3_bucket.lab.bucket == "deh-lab-tf-tests-ca-central-1"
error_message = "Le nom du bucket doit inclure le préfixe et la région."
}
assert {
condition = aws_s3_bucket.lab.tags["Project"] == "deh-wow"
error_message = "Tag Project manquant ou incorrect."
}
assert {
condition = var.aws_region == "ca-central-1"
error_message = "La région lab DEH est ca-central-1."
}
}
run "expect_bad_environment" {
command = plan
variables {
environment = "sandbox"
}
expect_failures = [
var.environment,
]
}
Points clés (reformulés, doc HashiCorp) :
run: scénario isolé (variables override possibles).assert:condition+error_messagelisible en CI.expect_failures: le run réussit si les validations listées échouent comme prévu.- Mocks (depuis 1.7) : data sources coûteuses — hors scope minimal ; vérifier la doc ≥ 1.9.
HowTo — Étape 3 : Exécuter terraform test
cd ~/lab-tf-tests-2026/module
terraform init -upgrade
terraform fmt -check && terraform validate
terraform test
terraform test -filter=tests/bucket_plan.tftest.hcl
- pass : asserts vraies ;
expect_failuresa capturé l’échec attendu. - fail : corrigez HCL ou test — pas le cloud « à la main ».
- Sans
command = plan, Terraform peut apply (puis cleanup framework). Préférezplanjusqu’à CI solide.
Cleanup : si un run apply a créé des ressources, laissez le framework nettoyer ou destroy sur un workspace lab dédié. Ne mélangez pas state prod et tests.
HowTo — Étape 4 : OPA / Conftest sur le plan JSON
terraform test valide le module. Conftest valide des politiques transverses sur le graphe du plan (tags, région, ACL).
cd ~/lab-tf-tests-2026/module
terraform plan -out=tfplan
terraform show -json tfplan > ../tfplan.json
policy/deny.rego (package main — namespace Conftest par défaut) :
package main
import future.keywords.if
import future.keywords.in
deny[msg] if {
some rc in input.configuration.root_module.resources
rc.type == "aws_s3_bucket"
region := input.configuration.provider_config.aws.expressions.region.constant_value
region != "ca-central-1"
msg := sprintf("région interdite %v — attendu ca-central-1", [region])
}
deny[msg] if {
some rc in input.resource_changes
rc.type == "aws_s3_bucket"
rc.change.actions[_] != "delete"
not rc.change.after.tags.Project
msg := sprintf("bucket %v : tag Project obligatoire", [rc.address])
}
Inspectez une fois tfplan.json avec jq : les chemins varient selon modules imbriqués / provider.
cd ~/lab-tf-tests-2026
conftest test tfplan.json -p policy/
Fail-closed : un deny non vide → exit ≠ 0 → PR bloquée. Complément naturel : asserts métier (terraform test) vs garde-fous org (Conftest).
HowTo — Étape 5 : Sketch CI GitHub Actions
name: terraform-test-opa
on:
pull_request:
paths: ["module/**", "tests/**", "policy/**"]
permissions:
contents: read
id-token: write
jobs:
unit-and-policy:
runs-on: ubuntu-latest
defaults:
run:
working-directory: module
steps:
- uses: actions/checkout@v4
- uses: hashicorp/setup-terraform@v3
with:
terraform_version: "1.9.8" # pin ≥ 1.9 — vérifier release
- name: Init / fmt / validate
run: |
terraform init -input=false
terraform fmt -check
terraform validate
- name: terraform test
run: terraform test
- name: Plan JSON + Conftest
working-directory: .
run: |
docker run --rm -v "$PWD":/project openpolicyagent/conftest
test /project/tfplan.json -p /project/policy
Plan AWS réel en CI : OIDC + rôle lecture. Les runs command = plan peuvent rester sans credentials si aucune data source authentifiée — sinon mocks (1.7+) ou stubs. Documentez le choix dans le README.
Erreurs fréquentes
| Symptôme | Cause probable | Correctif |
|---|---|---|
| Aucun test découvert | Mauvais dossier / extension | *.tftest.hcl ou .tftest.json ; lancer depuis le module |
| Ressources créées en « unit » | Défaut command = apply |
command = plan dans chaque run lab |
| Assert OK local, fail CI | Versions / Region / lock | Même providers, pin Terraform, ca-central-1 |
| Conftest silencieux | Mauvais chemin JSON Rego | jq sur resource_changes ; ajuster deny |
| Clés AWS dans le dépôt | Anti-pattern | AWS_PROFILE / SSO / OIDC uniquement |
| Confusion vs Terratest | Deux couches | Natif = module ; Terratest = intégration optionnelle |
FAQ
terraform test remplace-t-il Terratest en 2026 ?
Non. Il couvre l’unitaire/module en HCL. Terratest reste pour l’intégration post-apply. DEH : natif d’abord.
Pourquoi command = plan dans nos labs ?
Le défaut framework est apply. Le plan suffit pour naming, tags, validations — sans facturation.
Où placer les .tftest.hcl ?
Souvent tests/ à côté du module. Discovery automatique ; filtre possible avec -filter.
Conftest lit-il le HCL directement ?
Flux robuste : plan → show -json → Conftest. Le JSON porte resource_changes et la config.
Sentinel HCP est-il obligatoire ?
Non. OPA/Conftest reste portable en CI — voir wow-policy-as-code-opa et wow-conftest-ci.
Quiz (3 questions)
1. Valeur par défaut de command dans un run de terraform test ?
– A. plan
– B. apply
– C. validate
2. Test unitaire sans coût cloud sur un module S3 — pratique DEH ?
– A. command = plan + asserts sur attributs planifiés
– B. apply systématique puis destroy en prod
– C. Désactiver les providers AWS
3. Conftest sur Terraform s’appuie typiquement sur :
– A. Le seul fichier terraform.tfstate
– B. Le JSON de terraform show -json après plan -out
– C. Les commentaires # POLICY dans le HCL
Réponses : 1‑B · 2‑A · 3‑B
Pour aller plus loin
- HashiCorp — Tests (
run,assert,expect_failures, mocks) - OPA · Conftest
- CI :
hashicorp/setup-terraform
Maillage série Terraform + siblings WOW
| ← Bases | Overview · Install · Workflow |
| Modules / state | Modules bases · State S3 |
| WOW siblings | Policy-as-Code OPA · Conftest CI · OpenTofu vs Terraform |
| Landing | Terraform |
Meta publication (Rank Math / SEO) — PUBLISH GO
- Title SEO : Tests Terraform 2026 : terraform test + OPA/Conftest
- Meta description (≤ 155) : terraform test 2026 :
.tftest.hcl, asserts sur plan, puis OPA/Conftest sur plan JSON. Lab FR ca-central-1 — DevOps Elastic Hayway. - Focus keyword :
terraform test - Slug :
wow-terraform-tests-2026 - Image mise en avant :
assets/web/devopelastichayway/cover-wow-terraform-tests-2026-1200x630.webp(alt : Tests Terraform 2026 — terraform test et OPA/Conftest) - Catégorie : Terraform · Niveau : Intermédiaire · Parent WP :
/tutoriels/5463 - Statut publication : PUBLISH GO — auto-push WordPress (Maître)
Sources vérifiées (2026-09-11) : HashiCorp Terraform Language — Tests (discovery .tftest.hcl / .tftest.json, blocs run, command plan|apply défaut apply, assert, expect_failures, mocks depuis 1.7) ; docs Open Policy Agent ; docs Conftest. Versions : ≥ 1.9 / vérifier release — aucun patch inventé hors pin d’exemple CI.
Pour aller plus loin — hubs live
Retour parcours Catalogue Tutoriels — hub de la série et leçons sœurs.