Skip to main content

Outils open source pour tester du code Terraform

Écrit par
Headshot of Stephane Jourdan

Stephane Jourdan

feature synk iac terraform purple

14 mai 2020

0 minutes de lecture

Note de la rédaction : Ce billet a été publié à l’origine sur CloudSkiff.com. CloudSkiff a rejoint Snyk en octobre 2021.

Les tests du code Terraform sont un sujet récurrent qui revient souvent. Beaucoup de personnes s’interrogent sur les tests du code d’infrastructure, même si leur adoption dans la pratique reste limitée. Tout d’abord, faut-il tester votre code ? Quelles sont les différentes stratégies pour automatiser les tests, et quels sont les meilleurs outils open source pour y parvenir ?

Tester le code Terraform est essentiel : oui, vous devriez le faire. Il existe de nombreuses façons de procéder. C’est très similaire aux pratiques classiques du génie logiciel. Cela relève de la même culture, rien d’étonnant donc.

Tester le code Terraform : commencez par utiliser des linters

Vous pouvez exécuter les linters directement sur votre ordinateur ou dans votre système CI/CD afin de vous assurer que les autres respectent certaines conventions de codage ou normes.

J’aime beaucoup le linter Terraform TFLint. Il est open source et disponible sur Github. C’est un linter « adapté à l’infrastructure », ce qui signifie qu’il analyse votre code d’une manière que terraform validate ne permet pas. terraform validate est une sous-commande de Terraform. En gros, elle vérifie uniquement la validité de la structure, et non celle du contenu. Ainsi, si vous demandez un type incorrect de machine AWS, terraform validate ne le détectera pas comme étant invalide, contrairement à TFLint.

Voici à quoi ressemblerait un commit erroné :

Extrait de code Terraform définissant une variable instance_type avec une description de démonstration et la valeur par défaut « t3.nano »

Et voici comment il serait détecté et apparaîtrait dans vos journaux :

README présentant un cas de test qa-tflint-error signalant une valeur instance_type AWS non valide dans du code Terraform
Sortie du terminal montrant l’initialisation de Terraform, suivie d’une erreur indiquant un type d’instance AWS EC2 invalide.

Ce linter dispose également d’une fonction d’« analyse approfondie » qui va au-delà de la simple analyse statique.

Imaginons que vous deviez demander une VM existante et valide, par exemple une instance T3 large. Si votre compte ne dispose plus de capacité (par exemple, vous avez déjà lancé toutes les VM que vous étiez autorisé à demander), le linter envoie une requête à l’API AWS pour vérifier que votre demande est correcte et qu’elle peut être exécutée dans les limites de votre compte. Il effectue toutes les vérifications d’un bon linter en développement — qualité, tabulations, etc. — et va au-delà du validateur et du formateur intégrés à Terraform.

Un cas d’utilisation courant : vous avez effectué tous vos tests dans un environnement de préproduction, dont les limites AWS sont très élevées parce que vous avez envoyé des dizaines de requêtes au fil du temps, chaque fois que vous aviez besoin de tester quelque chose. Vous disposez peut-être ainsi de centaines, voire de milliers d’instances autorisées dans chaque région.

Mais vous décidez ensuite de déployer une nouvelle modification en production, et votre environnement de production n’a peut-être pas les mêmes règles ni les mêmes limites de compte AWS. Vous allez alors déployer quelque chose qui ne fonctionnera pas dans votre environnement de production.

Le linter approfondi vérifiera que ce que vous vous apprêtez à déployer en production depuis la préproduction, le développement ou tout autre environnement peut réellement fonctionner avec les autorisations de votre compte.

Effectuez des tests unitaires sur votre code Terraform avec le TDD‹

Un processus de développement Agile rigoureux commence par le développement piloté par les tests (TDD).

Quand vous commencez à pratiquer le TDD, vous écrivez des tests unitaires, par exemple : « Je veux créer mon VPC, qui doit disposer de cet espace d’adressage. » L’étape suivante consiste à écrire votre fonction (dans Terraform, on parle d’une ressource), puis à l’exécuter. Comme nous le verrons plus loin, j’utiliserais des outils dérivés de RSpec : Serverspec, InSpec… Les étapes de votre TDD ressembleraient à ceci :

Commencez par écrire votre test : il échoue

Écrivez la ressource : le test ne passe plus en échec, car elle sera lancée dans un environnement isolé (en particulier, ce VPC).

Au cours de ce processus, vous allez tester ce que vous vouliez, puis le détruire. Vous pouvez procéder comme en ingénierie, par exemple dans votre CI : exécuter tous les tests sur les pull requests. Au fait, déterminer le niveau de sécurité à mettre en place une fois que vous commencez à tester est un sujet délicat. Personnellement, j’exécute tous les tests avant toute fusion, mais je suis beaucoup moins strict pendant la phase de pull request, car lancer tous les tests en permanence, à chaque commit, peut prendre beaucoup de temps.

Effectuez des tests d’intégration

Une autre possibilité, assez courante dans les processus d’assurance qualité, consiste à randomiser des éléments comme les variables. Terratest est un autre outil vraiment intéressant pour les tests d’intégration. C’est probablement le plus complet, mais aussi le plus complexe.

Voyons cela de plus près.

Terratest est une bibliothèque Go. Il faut des compétences pour la maîtriser (eh oui, c’est du Go…), mais elle vous permet de tester tout ce qui possède une API, comme AWS, Azure, Google Cloud, Kubernetes, les images Docker, les builds Packer… (Packer est l’outil de Hashicorp pour créer des AMI : des images disque de machines virtuelles), ainsi que les charts Helm.

En gros, il vous suffit de créer le fichier nommé resource_test.go, d’importer vos bibliothèques et de l’exécuter. Mais cela exige un certain niveau de compétences en Go et une compréhension approfondie de ce que vous voulez tester.

Randomisez les éléments

Pendant cette phase d’intégration, je randomiserais des éléments comme les noms des régions. En général, vous testez toujours votre code dans la même région. En les randomisant, vous obtiendrez des résultats différents et vous pourrez vérifier que tout fonctionne.

Il se peut que vos noms soient uniques, tout comme ceux de vos ressources. Par exemple, votre bucket Amazon S3 doit être unique. Le processus est le même que pour un projet d’ingénierie :

Utilisez les outils

  • Analysez votre code avec un linter

  • Effectuez des tests unitaires sur vos fichiers

  • Randomisez ces éléments

  • Intégrez les résultats à votre CI

  • Ajoutez cela à vos pull requests

  • Ajoutez des tags à votre code et à vos versions (comme master)

  • Utilisez des branches de fonctionnalité, puis fusionnez-les dans master avant de publier une version du code

Autres outils que nous recommandons pour tester votre code d’infrastructure

J’ai mentionné les outils dérivés de RSpec : Serverspec, InSpec… InSpec est développé par Chef, tandis que Serverspec est davantage porté par la communauté, je crois.

Serverspec est conçu pour les tests unitaires, mais ne se limite pas à Terraform. Il est plus généraliste. Vous pouvez tout tester : de l’infrastructure aux images Docker, en passant par les processus exécutés sur un serveur et d’autres éléments de ce type. Sa syntaxe est lisible, proche de l’anglais. Il est vraiment polyvalent, car il ne teste pas directement le code et ne correspond pas directement au code Terraform de votre dépôt d’infrastructure. En revanche, il vérifie ce qui a réellement été lancé. Par exemple, si vous ajoutez une fonctionnalité, comme une base de données sur Google Cloud, et que vous voulez vérifier que le port « 5.4.3.2 » est ouvert, il vous suffit d’écrire ce test et de l’exécuter. Vous aurez ainsi la certitude, pour toujours, qu’un service répond sur ce port. Serverspec permet de le faire rapidement et facilement.

J’aime beaucoup un autre outil appelé GOSS. Il est open source et vraiment pratique. Très simple, il repose sur YAML. Il n’est pas du tout destiné à tester le code Terraform, mais plutôt à vérifier les résultats. Par exemple, vous avez créé un groupe de sécurité et vous voulez vous assurer que le port 22 pour SSH est fermé. Vous pouvez aussi tester les processus, les packages, le résolveur DNS, les utilisateurs… ou vérifier si votre point de terminaison HTTP sur Kubernetes répond, et bien d’autres choses encore…

Je crois qu’il peut même générer les résultats des tests dans un format compatible avec Nagios, ce qui vous permet de le lancer comme point /health dans votre microservice pour vérifier que tout fonctionne correctement. C’est un outil très simple et léger, que j’apprécie beaucoup. Il fonctionne très bien avec les fichiers Docker, etc.

Tester votre code Terraform

GOSS pour des vérifications simples et de haut niveau, avec du YAML simple et un binaire léger : facile à utiliser. Serverspec et InSpec pour tous les tests unitaires, et tout est open source.

Et Terratest, bien sûr, pour l’intégration. Il est très complet. Intégrez tout cela à votre système CI/CD, ou au moins à une étape précédant la livraison, la publication ou le déploiement. Sinon, vous risquez d’avoir des problèmes.

Pour détecter les vulnérabilités de sécurité dans votre code Terraform, Snyk IaC analyse vos configurations Terraform (ainsi que vos modèles Kubernetes, CloudFormation et ARM !) au fil de votre travail, et vous propose des correctifs guidés pour vous permettre de fusionner vos modifications et de poursuivre. Testez au fur et à mesure que vous écrivez, surveillez les changements dans vos dépôts Git et automatisez les tests dans vos pipelines de build avant le déploiement. Vous pouvez commencer en quelques minutes avec un forfait gratuit, tandis qu’une fuite due à une mauvaise configuration IaC peut causer des dommages durables. Inscrivez-vous ci-dessous pour commencer à sécuriser vos configurations.

Sécurisez votre infrastructure dès la source

Snyk automatise la sécurité et la conformité de l’IaC dans vos workflows, et détecte les ressources dont la configuration a dérivé ou qui sont manquantes.