Meta description : Tests Terraform 2026 : framework natif terraform test (.tftest.hcl), asserts sur plan, puis policies OPA/Conftest sur le plan JSON. Lab FR pratique en ca-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.hcl avec command = plan et assert, 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

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_message lisible 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_failures a 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érez plan jusqu’à 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

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.

← Catalogue Tutoriels

Pour aller plus loin — hubs live

Retour parcours Catalogue Tutoriels — hub de la série et leçons sœurs.