Tester un contrat de module

ShellBeginner
Pratiquer maintenant

Introduction

Une configuration peut être formatée et structurellement valide tout en étiquetant incorrectement un environnement de rapports. Votre équipe a besoin de contrôles exécutables des entrées, des sorties et des tags planifiés d'un petit module de stockage avant de se fier à un plan de livraison.

Vous allez écrire un contrat de module, tester deux environnements pris en charge et une entrée non prise en charge, et faire arrêter la tâche par un véritable défaut métier. Vous devez comprendre les variables et sorties de module ainsi que les contrôles bloquants de formatage et de validation du lab précédent. Le stockage de référence existant doit rester inchangé.

Liens avec les certifications

Certification Tâche de l'examen Mise en pratique
DevOps Engineer – Professional (DOP-C02) Tâche 1.2 S'exercer aux bases de l'intégration d'assertions de module exécutables à un contrôle qualité automatisé.

Les entrées du module sont vérifiées par des assertions en mode plan avant un plan de livraison, tandis que le stockage de référence est préservé.

Définir le contrat d'entrée

Dans cette étape, vous allez définir les entrées d'environnement acceptées par le module de stockage. La validation d'entrée rejette une demande non prise en charge avant de créer un plan de ressources.

Entrez dans le module fourni et chargez les outils préparés.

cd /home/labex/project/report-module
source environment.sh

Lisez son interface et l'implémentation des ressources.

cat variables.tf main.tf outputs.tf pipeline.json

environment sélectionne preview ou review ; bucket_prefix distingue les noms de stockage d'un appelant. Le nom du bucket combine les deux entrées, et le tag Environment et la sortie doivent identifier l'environnement demandé. Les fichiers fournis main.tf, outputs.tf, provider.tf et run-job.py doivent être préservés : gardez leur contenu final inchangé. Votre travail porte sur variables.tf, tests/ et pipeline.json.

Ajoutez un bloc validation à environment. contains vérifie l'appartenance à la liste prise en charge ; une condition fausse produit le message d'erreur fourni. Le document intégré avec délimiteur entre guillemets écrit du HCL littéral.

cat > variables.tf <<'EOF'
variable "environment" {
  type    = string
  default = "preview"
  validation {
    condition     = contains(["preview", "review"], var.environment)
    error_message = "Choose preview or review."
  }
}
variable "bucket_prefix" {
  type    = string
  default = "delivery-contract"
}
EOF

Formatez votre modification.

terraform fmt

Essayez une demande non prise en charge. -var fournit une valeur pour cette invocation. Cette commande renvoie intentionnellement le code de sortie natif 1 ; elle doit indiquer Choose preview or review., au lieu de proposer un bucket de production.

terraform plan -input=false -var=environment=production

La validation définit l'interface acceptée. À l'étape suivante, les tests exerceront les deux valeurs acceptées et ce rejet attendu.

Écrire des assertions et observer un échec réel

Dans cette étape, vous allez utiliser la commande native terraform test pour contrôler le comportement planifié du module. Le formatage et la validation peuvent accepter une sortie codée en dur mais incorrecte ; une assertion compare le résultat calculé à l'entrée demandée.

Terraform lit les fichiers .tftest.hcl sous tests/. Chaque run est un scénario de test indépendant. L'instruction explicite command = plan évalue un plan sans l'appliquer. Gardez les fichiers de test sous tests/ au format .tftest.hcl. Dans ce lab, chaque exécution doit utiliser le mode plan et le fournisseur/module fourni ; les modules alternatifs, les doublures de fournisseurs et les substitutions sortent du cadre de la tâche. Gardez bucket_prefix hérité de l'entrée de la suite : ne l'affectez pas dans les variables de test au niveau du fichier ou de l'exécution, afin qu'un appelant puisse sélectionner un autre préfixe légitime. Ces tests contrôlent des valeurs connues du plan, pas la création réelle, les autorisations à l'exécution ni une application déployée.

Créez le répertoire de tests. mkdir -p le crée si nécessaire et accepte un répertoire existant.

mkdir -p tests

Écrivez des assertions pour l'environnement par défaut et l'environnement alternatif. var désigne les entrées de l'exécution, les références de ressources inspectent les valeurs planifiées et output désigne les sorties du module. expect_failures exige l'échec de la validation de la variable nommée ; il ne transforme pas des erreurs arbitraires de fournisseur ou de réseau en tests réussis.

cat > tests/contract.tftest.hcl <<'EOF'
run "preview_contract" {
  command = plan
  assert {
    condition     = output.environment == var.environment
    error_message = "The output must identify the requested environment."
  }
  assert {
    condition     = aws_s3_bucket.reports.bucket == "${var.bucket_prefix}-${var.environment}"
    error_message = "The bucket name must use the requested prefix and environment."
  }
  assert {
    condition     = aws_s3_bucket.reports.tags.Environment == var.environment
    error_message = "The planned tag must identify the requested environment."
  }
}
run "review_contract" {
  command = plan
  variables { environment = "review" }
  assert {
    condition     = output.environment == var.environment
    error_message = "The alternate environment must not use the default label."
  }
  assert {
    condition     = aws_s3_bucket.reports.bucket == "${var.bucket_prefix}-${var.environment}"
    error_message = "The alternate bucket must use its requested inputs."
  }
  assert {
    condition     = aws_s3_bucket.reports.tags.Environment == var.environment
    error_message = "The alternate environment tag must match its input."
  }
}
run "unsupported_environment" {
  command         = plan
  variables { environment = "production" }
  expect_failures = [var.environment]
}
EOF

Formatez récursivement les tests et les fichiers du module.

terraform fmt -recursive

Exécutez la suite de tests.

terraform test

Trois exécutions réussies et un récapitulatif de réussite sont attendus. Aucun bucket de test n'est déployé. Les valeurs d'entrée et de sortie proviennent d'un véritable plan Terraform utilisant le fournisseur configuré.

Prouvez que vos assertions détectent un défaut plausible. Remplacez temporairement uniquement la sortie d'environnement par un libellé par défaut fixe ; conservez la sortie du nom de bucket.

cat > outputs.tf <<'EOF'
output "environment" {
  value = "preview"
}
output "bucket_name" {
  value = aws_s3_bucket.reports.bucket
}
EOF

Exécutez à nouveau la suite. Cette commande renvoie intentionnellement le code de sortie natif 1. L'assertion de l'environnement alternatif doit échouer, montrant qu'un HCL valide peut encore violer le contrat du module.

terraform test

Restaurez l'implémentation de sortie fournie depuis Git. Cela retire votre défaut temporaire tout en conservant la validation et les tests que vous avez écrits.

git restore -- outputs.tf

Exécutez l'implémentation corrigée avec les mêmes assertions.

terraform test

Toutes les exécutions doivent à nouveau réussir. Les tests doivent accepter des entrées légitimes, au lieu de simplement reconnaître une sortie par défaut.

Faire arrêter la tâche de livraison par les tests

Dans cette étape, vous allez placer les tests de modules entre les contrôles statiques et la planification. L'exécuteur fourni fait partie de la préparation ; modifiez la configuration des étapes au lieu de changer run-job.py.

Ajoutez test après fmt/validate et avant plan.

cat > pipeline.json <<'EOF'
{"stages":["fmt","validate","test","plan"]}
EOF

Exécutez la tâche complète.

python3 run-job.py

Les quatre étapes doivent réussir. Le plan final peut renvoyer le code natif 2, car ce module n'a pas été appliqué ; le runner le traite comme un aperçu réussi. Un test échoué doit au contraire arrêter la tâche avant son étape plan. Aucune étape d'application n'existe.

Exécutez la suite avec un autre préfixe de bucket légitime. Ce -var change l'entrée de la suite sans modifier le module ni ses tests.

terraform test -var=bucket_prefix=audit-contract

Les trois mêmes exécutions doivent réussir. Pour cet exercice, gardez bucket_prefix hérité de l'appelant dans chaque exécution : ne l'affectez pas dans les blocs variables du fichier de test ou des exécutions. De telles affectations remplacent les entrées de test CLI et empêcheraient cette commande d'exercer le préfixe demandé. Les remplacements de l'environnement restent nécessaires pour tester les deux environnements pris en charge. Les assertions construites à partir des entrées demandées continuent de fonctionner quand l'appelant choisit un autre nom valide.

Lisez le rapport de référence existant directement depuis le stockage. Ces buckets préparés appartiennent à un autre environnement ; ne les détruisez pas et ne les modifiez pas.

aws s3   cp s3://delivery-reference-reports/report.txt -

Il doit toujours contenir reference report v1. Vérifiez aussi les données voisines.

aws s3   cp s3://delivery-reference-neighbor/keep.txt -

Le résultat attendu est preserve contract neighbor. Vos tests n'ont créé aucune ressource de stockage ; il n'y a donc aucune pile de test à détruire. Conservez le contrat d'entrée, les tests et la configuration du pipeline pour la vérification finale ; le défaut temporaire de sortie a déjà été retiré.

Résumé

Vous avez défini un contrat d'entrée pris en charge, utilisé les tests Terraform natifs en mode plan pour comparer les sorties et les tags planifiés aux entrées et observé un véritable échec d'assertion. Vous avez ensuite intégré les tests au contrôle qualité de livraison tout en préservant les données existantes et l'état métier.

Les tests en mode plan n'établissent pas le comportement déployé. Les étapes de livraison ultérieures combinent ces contrôles avec un plan concret examiné et une application réelle contrôlée. Consultez la référence officielle de Terraform test et la documentation de configuration des tests pour les mécanismes pratiqués ici.