By Lionel Gurret.
Dans le monde Agile, les équipes de développement sont amenées à réduire autant que possible le temps de livraison tout en améliorant de façon continue la qualité du code produit.
En effet, il est important qu’à chaque release, la version soit documentée, testée, validée et sécurisée avant d’être déployée.
Pour cela, il est important que ces étapes soient intégrées au plus tôt dans le pipeline d’intégration continue avant même d’atteindre les équipes de testing.
Nous utilisons le terme de "shift left testing".
L’attention portée à la qualité du code est différente d’une approche traditionnelle, qui elle s’établit sur le tard, principalement avant le déploiement de l’application :
Source: https://devopedia.org/shift-left
Dans une approche "shift left testing", nous prenons en compte la qualité et la sécurité du code dès l’environnement de développement :
Les bénéfices d’une telle approche sont nombreux :
Il est important de rappeler que cela ne doit en aucun cas substituer les contrôles de sécurité et de qualité de code lors de la CI. Cette pratique permet d’améliorer la productivité en poussant un code pré-testé avant validation lors d’une Pull Request.
Dans cet article, nous allons détailler cette approche dans un context d’IaC (Infrastructure as Code) avec Terraform.
L’objectif serait d’intégrer dans notre chaîne de CI / CD des outils permettant de tester et valider la qualité et la sécurité de notre code Terraform dès que possible.
Nous allons constater qu’il est possible de lancer automatiquement certains de ces outils avant même que le code ne soit poussé dans le dépôt GIT par le développeur.
Avant d’entrer dans le coeur de sujet, il me parait important de rappeler certaines bonnes pratiques Terraform directement liées au sujet de cet article de blog.
Dans notre contexte de shift left testing, il serait judicieux d’intégrer au plus tôt les aspects suivants :
Je vous invite par ailleurs à consulter ce site dédié à l’utilisation de cet outil pour plus d’informations relatives aux bonnes pratiques.
L’utilisation des pre-commits GIT permet d’appeler des hooks avant chaque message de commit afin le lancer automatiquement des scripts personnalisés ou des commandes.
Ces derniers vont nous permettre par exemple de vérifier la syntaxe de notre code Terraform, ou comme vu précédemment, tester la sécurité et la qualité de notre code.
Pour pouvoir utiliser les pre-commits, il est nécessaire d’installer le package pre-commit sur votre environnement de développement (ici WSL).
Lancer simplement la commande pip suivante :
pip install pre-commit
Ces deux outils intégrés à la CLI Terraform, vont nous permettre de formater notre code et de le valider avant de l’utiliser.
Description | Documentation |
---|---|
Checkov est un outil d’analyse de code statique pour l’Infrastructure as Code. Il analyse l’infrastructure cloud provisionnée à l’aide de Terraform, Terraform plan, Cloudformation, AWS SAM, Kubernetes, Helm charts, Kustomize, Dockerfile, Serverless, Bicep ou ARM Templates et détecte les erreurs de configuration de sécurité et de conformité. | Checkov |
Exemple :
En lançant la commande suivante sur un projet Terraform provisionnant des ressources dans le cloud Azure, il nous est possible d’obtenir une analyse poussée de Checkov sur notre code.
checkov --directory my_terraform_directory
Pour commencer, Checkov affiche le résultat de son analyse (ici 16 points validés mais 40 problématiques) ainsi que le détail des points validés :
Ensuite, les points d’amélioration sont affichés avec un lien renvoyant directement vers la documentation permettant d’améliorer ses _manifests _Terraform :
Comme vous pouvez le constater en vous rendant dans la documentation fournie par Checkov, le storage account devrait contenir une network access rule (règle d’accès réseau), configurée à deny par défaut :
Description | Documentation |
---|---|
Cet utilitaire permet de générer de la documentation à partir de modules Terraform dans divers formats de sortie (json, asciidoc, pretty, xml etc.). | terraform-docs |
Exemple :
Dans cet exemple, nous allons générer une documentation au format markdown basée sur un code Terraform utilisé pour provisionner des ressources AWS et Consul.
Il suffit de se rendre dans notre répertoire contenant nos manifests Terraform et de lancer la commande suivante :
terraform-docs markdown table . > Readme.md
Le contenu de notre fichier généré est le suivant :
Nous observons la génération d’une documentation complète, contenant tous les blocs Terraform organisés sous forme de tableaux détaillés !
Enfin, une dernière note importante liée directement à pre-commit-terraform et terraform-docs !
Si vous ajoutez dans votre Readme.md les balises suivantes, votre documentation terraform sera automatiquement poussée entre ces balises !
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
Cela vous permet de conserver dans votre documentation une partie statique et laisser terraform-docs remplir de façon dynamique, la partie relative à Terraform.
Description | Documentation |
---|---|
Terragrunt fournit des fonctions supplémentaires pour garder vos configurations DRY (« Don’t Repeat Yourself »), travailler avec plusieurs modules Terraform et gérer l’état à distance. | terragrunt |
Exemple :
Il est possible de tirer profit de Terragrunt (via son fichier terragrunt.hcl) dans différentes situations :
Dans le contexte de cet article, je n’ai pas utilisé Terragrunt. Cependant, pre-commit-terraform permet de l’intégrer.
Description | Documentation |
---|---|
Terrascan est un analyseur de code statique pour Infrastructure as Code permettant de détecter les erreurs de configuration, les vulnérabilités de sécurité et les violations de conformité. | terrascan |
Exemple :
En lançant la commande suivante dans un répertoire contenant nos _manifests _Terraform:
terrascan scan
Nous pouvons observer certains points d’améliorations détectés par terrascan.
Nous observons ici 3 non-conformités dont 2 critiques.
L’un des avantages de terrascan est qu’il présente les différentes améliorations possibles avec des niveaux de criticité. Ce point peut permettre, par exemple, de bloquer un pipeline lorsqu’un point considéré comme critique par terrascan est détecté.
Description | Documentation |
---|---|
TFLint permet de détecter certaines erreurs (comme des types d’instances illégaux) pour les principaux fournisseurs de cloud (AWS/Azure/GCP). Cet outil détecte les syntaxes obsolètes, les déclarations inutilisées. Et enfin, permet d’appliquer les meilleures pratiques, notamment sur les conventions de nommage. | tflint |
Exemple :
Dans cet exemple, TFLint détecte automatiquement que la syntaxe utilisée dans les manifests Terraform pour AWS est obsolète (en l’occurence le type d’instance) :
Cet outil va nous permettre d’observer automatiquement les changements des _cloud providers _pour ensuite adapter notre code afin d’éviter l’utilisation de ressources obsolètes ou encore de déclarer inutilement des variables.
Description | Documentation |
---|---|
tfsec utilise une analyse statique de vos modèles de terraform pour détecter les problèmes de sécurité potentiels. | tfsec |
Exemple :
Dans cet exemple, tfsec détecte une vulnérabilité critique liée à un storage container azure :
Des liens sont fournis pour remédier aux différents problèmes.
Tout comme terrascan, tfsec classe les problèmes par sévérité. Ce point peut permettre, par exemple, de bloquer un pipeline lorsqu’un point considéré comme critique est détecté.
Description | Documentation |
---|---|
Attention, afin d’utiliser infracost, il est nécessaire d’installer au préalable jq! Infracost affiche les estimations de coût du cloud pour Terraform. Il permet aux DevOps, SRE et aux ingénieurs de comprendre les coûts avant d’apporter des modifications, que ce soit dans le terminal ou les pull requests. | infracost |
Exemple :
En utilisant infracost, il est possible dans un premier temps d’afficher le coût total de notre infrastructure.
Ici un exemple AWS :
Ensuite il est possible en utilisant l’argument diff, d’estimer le prix répercuté par nos changements :
Cet outil a donc comme vocation d’afficher le prix total de notre infrastructure ou de mesurer l’impact financier des changements apportés à nos manifests. Il est donc possible d’en profiter pour bloquer un pipeline Terraform lorsque les coûts engendrés par nos modifications sont trop élevés et éviter ainsi des dépenses hasardeuses.
Ce genre d’outil a selon moi d’avantage sa place dans la CI que sur l’environnement de développement. En effet, pour lancer une estimation des coûts sur son laptop, le développeur doit conserver en local les clefs d’API. Il me parait plus intéressant de traiter ce point, d’un point de vue global dans le pipeline de CI/CD.
Maintenant que nous avons décrit les différents outils appelés par terraform-pre-commit, nous pouvons passer aux choses sérieuses : utiliser ces outils dans les pre-commit GIT !
Pour cela, il est important d’avoir :
Lancer les commandes suivantes pour installer globalement le hook pre-commit :
# Initialisation de pre-commit
DIR=~/.git-template
git config --global init.templateDir ${DIR}
pre-commit init-templatedir -t pre-commit ${DIR}
# Création de la configuration de pre-commit (exemple)
cat <<EOF > .pre-commit-config.yaml
repos:
- repo: https://github.com/antonbabenko/pre-commit-terraform
rev: v1.64.0 # Get the latest from: https://github.com/antonbabenko/pre-commit-terraform/releases
hooks:
- id: terraform_fmt
args:
- --args=-no-color
- --args=-diff
- --args=-write=false
- id: terraform_docs
args:
- --hook-config=--create-file-if-not-exist=true # you can pass args to hooks !
- id: checkov
- id: terrascan
- id: terraform_tfsec
# - To complete ! Use what you want / need !!!
EOF
Nous pouvons maintenant tester notre pre-commit hook !
pre-commit run -a
Nous observons qu’automatiquement nos outils sont appelés.
_Terraform fmt _et _Terraform docs _n’ont pas rencontrés de soucis mais _tfsec _a détecté des failles de sécurité dans notre code :
Dans cet exemple, avant que le développeur puisse pousser son code sur le dépôt GIT, ce dernier a été formaté, documenté et testé !
N’hésitez pas à consulter la documentation de pre-commit-terraform pour connaître toutes les configurations possibles !
Comme nous avons pu le constater, il est relativement simple d’ajouter et de tirer à profit les pre-commits dans un contexte de développement Terraform. Cette bonne pratique va nous permettre de déplacer les tests de sécurité au plus tôt dans notre pipeline de CI.
Cependant, il reste toujours la possibilité d’ignorer les pre-commits (git commit . -m ‘quick fix’ –no-verify ou tout simplement en n’installant pas les outils nécessaires.)
Il est donc très important de ne pas ignorer ces outils dans nos pipelines de CI !
Il peut donc être judicieux de ne pas rendre le process trop compliqué pour les développeurs en se limitant par exemple au formatage du code, à sa validation et aux failles critiques détectées par des outils comme TFSec ou Checkov. Le code soumis lors des Pull Requests ne sera que plus propre et a minima testé.
https://www.terraform-best-practices.com/
https://www.youtube.com/watch?v=ziJK79tI6tY