Aller au contenu

TP 27 : Tester un module avec des mocks

À l’issue de ce TP, vous serez capable de :

  • écrire un fichier .tftest.hcl avec des blocs run ;
  • distinguer un test en mode plan d’un test en mode apply ;
  • simuler un provider entier avec mock_provider pour tester sans coût ni credentials ;
  • surcharger une ressource ou une data source avec override_resource / override_data ;
  • écrire des assertions sur les valeurs calculées.
  • Terraform >= 1.7 (les mocks du framework de test sont disponibles depuis la 1.7 ; terraform test est GA depuis la 1.6).
  • Aucun credential cloud n’est nécessaire grâce aux mocks.

InfraBank veut valider ses modules Terraform en CI, rapidement et sans créer de vraies ressources AWS (coût, lenteur, credentials). Les mocks permettent de tester la logique du module de façon déterministe.

main.tf
variable "name" {
type = 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" "this" {
bucket = "${var.name}-${var.environment}"
}
resource "aws_s3_bucket_versioning" "this" {
bucket = aws_s3_bucket.this.id
versioning_configuration {
status = var.environment == "prod" ? "Enabled" : "Suspended"
}
}
output "bucket_name" {
value = aws_s3_bucket.this.bucket
}
output "versioning_status" {
value = aws_s3_bucket_versioning.this.versioning_configuration[0].status
}
versions.tf
terraform {
required_version = ">= 1.7"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.60"
}
}
}

Étape 2 : Un premier test en mode plan avec mock_provider

Section intitulée « Étape 2 : Un premier test en mode plan avec mock_provider »

Les fichiers de test se placent dans un dossier tests/ et portent l’extension .tftest.hcl.

tests/naming.tftest.hcl
mock_provider "aws" {}
run "nom_bucket_construit" {
command = plan
variables {
name = "infrabank"
environment = "dev"
}
assert {
condition = aws_s3_bucket.this.bucket == "infrabank-dev"
error_message = "Le nom du bucket devrait être infrabank-dev."
}
}

mock_provider "aws" {} remplace tout le provider AWS par une implémentation factice : aucune API n’est appelée, aucune ressource n’est créée. command = plan évalue la configuration sans apply.

Fenêtre de terminal
terraform init
terraform test

Le framework sait vérifier qu’une entrée invalide échoue bien, grâce à expect_failures :

tests/validation.tftest.hcl
mock_provider "aws" {}
run "environnement_invalide_rejete" {
command = plan
variables {
name = "infrabank"
environment = "qa" # non autorisé
}
expect_failures = [
var.environment,
]
}

Étape 4 : Tester la logique conditionnelle en mode apply

Section intitulée « Étape 4 : Tester la logique conditionnelle en mode apply »

En mode apply avec mock, Terraform « crée » les ressources mockées et calcule les attributs, ce qui permet de tester la logique de bout en bout.

tests/versioning.tftest.hcl
mock_provider "aws" {}
run "prod_active_le_versioning" {
command = apply
variables {
name = "infrabank"
environment = "prod"
}
assert {
condition = output.versioning_status == "Enabled"
error_message = "Le versioning doit être Enabled en prod."
}
}
run "dev_suspend_le_versioning" {
command = apply
variables {
name = "infrabank"
environment = "dev"
}
assert {
condition = output.versioning_status == "Suspended"
error_message = "Le versioning doit être Suspended hors prod."
}
}

Par défaut, un mock renvoie des valeurs générées pour les attributs calculés. Pour forcer une valeur déterministe (utile quand un attribut calculé alimente la logique), utilisez override_resource ou override_data :

tests/override.tftest.hcl
mock_provider "aws" {}
override_resource {
target = aws_s3_bucket.this
values = {
arn = "arn:aws:s3:::infrabank-prod"
}
}
run "arn_force" {
command = apply
variables {
name = "infrabank"
environment = "prod"
}
assert {
condition = aws_s3_bucket.this.arn == "arn:aws:s3:::infrabank-prod"
error_message = "L'ARN mocké devrait être forcé."
}
}

override_data fonctionne de la même façon pour une data source, et override_module pour un module appelé.

Fenêtre de terminal
terraform test

Sortie attendue (extrait) :

tests/naming.tftest.hcl... pass
tests/validation.tftest.hcl... pass
tests/versioning.tftest.hcl... pass
tests/override.tftest.hcl... pass
Success! 5 passed, 0 failed.

Pour un rapport exploitable en CI :

Fenêtre de terminal
terraform test -junit-xml=report.xml
  • terraform test passe sans aucun credential AWS.
  • Aucune ressource réelle n’apparaît dans votre compte.
  • Un environnement invalide est bien rejeté par le test expect_failures.

Rien à détruire : aucune ressource réelle n’a été créée.

Fenêtre de terminal
rm -f report.xml