Blog ENI : Toute la veille numérique !
Accès illimité 24h/24 à tous nos livres & vidéos ! 
Découvrez la Bibliothèque Numérique ENI. Cliquez ici
Accès illimité 24h/24 à tous nos livres & vidéos ! 
Découvrez la Bibliothèque Numérique ENI. Cliquez ici
  1. Livres et vidéos
  2. L’infrastructure as Code avec Terraform
  3. Tester le code Terraform
Extrait - L’infrastructure as Code avec Terraform Déployez votre infrastructure sur le Cloud
Extraits du livre
L’infrastructure as Code avec Terraform Déployez votre infrastructure sur le Cloud Revenir à la page d'achat du livre

Tester le code Terraform

Pourquoi tester ?

Lorsqu’on travaille avec Terraform, il est important de pouvoir être capable de tester le code.

Des ressources mal provisionnées ou mal configurées peuvent avoir des conséquences coûteuses, en temps et en argent.

Des tests permettent de garantir le bon fonctionnement du code et son exactitude. Ils valident que les ressources ou modules Terraform sont bien implémentés avant de les déployer dans des environnements de production.

La présence de tests dans un module rend aussi plus faciles les modifications. L’existence de tests automatisés pouvant être relancés à la demande permet de valider que les nouvelles n’introduisent pas de régressions.

Les tests dans Terraform ont longtemps été mal outillés. Des frameworks de test écrits en Go comme TerraTest avaient comblé ce manque, mais leur utilisation impliquait de développer les tests en Go. Depuis la version 1.6 de Terraform, les tests sont officiellement supportés, sans avoir besoin d’outillage complémentaire ! Les tests étaient en version expérimentale depuis la version 0.15 !

1. Tests d’intégration

Le code Terraform peut être testé avec la commande terraform test. Les tests tels qu’ils sont implémentés par terraform test sont des tests d’intégration. Lors...

Tests d’intégration

Les tests sont écrits dans des fichiers .tftest.hcl. Ces fichiers peuvent être présents à la racine du code source, ou dans un répertoire nommé tests :

. 
├─ main.tf 
├─ provider.tf 
├─ variables.tf 
└─ tests 
   └─ main.tftest.hcl 

L’utilisation d’un répertoire tests est l’option à privilégier lorsque le code contient plus que quelques fichiers, en particulier pour les modules complets comportant des exemples et de multiples fichiers de code.

Un test est composé d’un ou plusieurs blocs run, qui contient un ou plusieurs blocs assert. Un bloc variables permet d’initialiser les variables dans le contexte du test :

run "<TEST_NAME>" { 
 
  variables { 
    <NAME> = <VALUE> 
  } 
 
  assert { 
    condition = <EXPRESSION> 
    error_message = "<MESSAGE>" 
  } 
 
} 

Pour illustrer l’écriture de blocs run, voici un exemple de code qui crée un bucket sur GCP en utilisant les valeurs de deux variables :

variable "bucket_name" {} 
 
variable "region"...

Tests de plan

Lorsque l’on souhaite tester des attributs qui sont calculés par Terraform et non pas par le provider de cloud, on peut demander à terraform test d’uniquement exécuter un terraform plan à la place d’un apply.

Pour avoir ce comportement, il faut ajouter dans le bloc run souhaité l’argument command = plan :

run "validate_bucket_name_plan_only" { 
 
  command = plan 
 
  variables { 
    bucket_name = "dagobah" 
    region = "EU" 
  } 
 
  assert { 
    condition = google_storage_bucket.this.name == "gcs-dagobah-eu" 
    error_message = "Bucket name does not match" 
  } 
} 

Le test s’exécute alors de la même manière, mais aucune ressource n’est créée pendant l’exécution :

$ terraform test 
 
tests/test_plan.tftest.hcl... in progress 
  run "validate_bucket_name_plan_only"... pass 
tests/test_plan.tftest.hcl... tearing down 
tests/test_plan.tftest.hcl... pass 
 
Success! 1 passed, 0 failed. 

Les tests command = plan sont plus rapides d’exécution que les tests utilisant un apply. Ils sont à...

Tests avec des mocks

Les mocks sont de faux objets que l’on peut utiliser dans des tests pour simuler une partie de l’exécution du code Terraform.

Le mock vient alors prendre la place de l’objet qu’il désigne.

Dans les tests Terraform, les mocks sont particulièrement intéressants lorsque des modules utilisent des blocs data. Par contre, comme ils simulent une partie de l’infrastructure, les tests qui utilisent des mocks sont forcément moins fiables.

Terraform permet de créer des mocks à plusieurs niveaux : pour un provider complet, pour des blocs data, ou pour des blocs resource.

Voici un exemple de code d’un module plus complexe. Il s’agit d’un module qui crée un utilisateur dans une base de données existante :

variable "database_instance_name" { 
  type = string 
} 
 
variable "username" { 
  type = string 
  sensitive = true 
} 
 
variable "password" { 
  type = string 
  nullable = true 
  default = null 
} 

Les variables en entrée sont le nom de l’instance de base de données dans laquelle l’utilisateur doit être créé, le nom de l’utilisateur à créer, et le mot de passe à utiliser. Le mot de passe peut être null, c’est d’ailleurs sa valeur par défaut.

locals { 
  generate_password = var.password == null ? true : false 
  computed_password = local.generate_password ? 
random_password.db_password[0].result : var.password 
} 
 
resource "random_password" "db_password" { 
  count = local.generate_password ? 1 : 0 
 
  length = 16 
  special = true 
} 
 
data "scaleway_rdb_instance" "instance" { 
  name = var.database_instance_name 
} 
 
resource "scaleway_rdb_user" "db_user" { 
  instance_id = data.scaleway_rdb_instance.instance.id 
  name = var.username 
  password = local.computed_password 
  is_admin = true 
} 

Le code du module déclare une ressource...

Checks

Les checks permettent de valider la configuration de l’infrastructure après qu’elle soit créée. Ils peuvent être utilisés pour s’assurer qu’un load-balancer écoute bien en HTTP, qu’une machine ou une base de données est bien démarrée, etc.

Les checks sont exécutés après terraform plan et terraform apply. Ils n’ont pas d’impact sur la création des ressources et ils ne déclenchent pas de blocage du déploiement, ou de retour arrière. Ils ont purement un aspect informatif, pour contrôler l’état de l’infrastructure.

Les checks utilisent la même syntaxe de bloc assert que les tests.

Un bloc check s’écrit dans le code Terraform avec la syntaxe suivante :

check "<CHECK_NAME>" { 
 
  assert { 
    condition = <EXPRESSION> 
    error_message = "<MESSAGE>" 
  } 
 
} 

Voici un exemple de ressource, accompagnée d’un bloc check, qui valide qu’une instance est bien à l’état started :

resource "scaleway_instance_server" "web" { 
  name = "web" 
  type = "DEV1-S" 
  image = "ubuntu_jammy" ...

Conclusion

Ce chapitre a présenté les tests en Terraform, ainsi que les Check dont le fonctionnement est très proche des Smoke Tests. L’utilisation des tests permet de rendre vos modules plus stables et de valider leur bon fonctionnement avant de les publier sur le Registry Terraform !

Ce chapitre est le dernier qui porte sur l’écriture de code Terraform en HCL.

Le suivant introduit l’écriture d’un provider en Go, pour mieux comprendre le fonctionnement interne de Terraform et être capable de modifier ou de développer votre propre provider.

Si vous développez votre propre service cloud ou votre propre SaaS, le prochain chapitre vous donnera les bases suffisantes pour débuter !