Automatiser la génération des fichiers de configuration (IaC) en Terraform d'un projet existant ?

janvier 2022

Sujet 5 : Quelles (bonnes) pratiques automatisables pour les systèmes de déploiement comme Ansible ou Terraform ?

Auteurs

Contexte

Des technologies comme Ansible ou Terraform permettent d’automatiser le déploiement de systèmes sur des infrastructures cloud et d’en configurer plusieurs aspects (ex. cloud provider, …). Chacun de ces deux systèmes IaC (Infrastructure As Code) dispose de sa propre organisation, de certains outillages standards (linter, afficheur, …) ou fournis par la communauté, et de bonnes pratiques qui émergent sans être forcément bien établis. On trouve des réponses dans des forums connus (StackOverflow), des billets de blog dont on ne sait pas si ce sont des pratiques répétées ou un retour d’expérience après un seul déploiement, etc. L’ensemble forme une jungle désorganisée de pratiques.

Question principale :

Comment automatiser la génération des fichiers de configuration (IaC) en Terraform d’un projet existant ? Nous pensons que cette question est pertinente parce qu’un Template de configuration peut aider les développeurs à développer et déployer plus vite. Nous avons fait le choix d’utiliser Terraform au lieu d’Ansible parce qu’il a sa propre extension de fichier et langage dédié HCL (contrairement à Ansible qui utilise YAML) ce qui peut rendre l’identification d’un projet utilisant Terraform plus facile. Etant un outil déclaratif Terraform nous permettra de définir le modèle d’exécution du projet à automatiser contrairement à Ansible (impératif) qui est plus orienté sur comment le faire.

Recherches

Nous avons détaillé notre question principale en deux sous-questions auxquelles nous allons essayer de répondre.

Terraform

Terraform est un outil logiciel d’Infrastructure as Code créé le 28 juillet 2014 par la société HashiCorp. Les utilisateurs définissent leur infrastructure en utilisant le langage HCL. Terraform permet de décrire le déploiement d’une solution logicielle dans le cloud sous forme de fichiers. Il supporte notamment les principaux fournisseurs de cloud comme par exemple Google, Amazon web services, Azure.

Bonnes pratiques : Conventions d’écriture de code

Terraform est un outil permettant au développeur de configurer comment il veut déployer une application sur le cloud. Certaines conventions sont encouragées par les développeurs de Terraform pour rendre le code Terraform plus accessible. Ainsi le nommage suivant est encouragé pour un projet de taille moyenne.

Nous avons regardé plusieurs projets pour vérifier s’ils respectent les bonnes pratiques de terraform, que nous avons précisé dans le paragraphe précédent.

Projets Description Pertinence Bonne pratiques Mauvaise pratiques
https://github.com/millieindeed/interview-static-site/tree/master Créer un site web static et le déployer sur aws pour une interview Ce projet a été archivé Oui, car il y a un fichier main.tf, un fichier contenant les varaibles et un fichier pour les resources Non
https://github.com/clburlison/clburlison.com/tree/master Un site web personnel centaine de commits et trois contributeurs utilisation d’un fichier pour les variables et d’un fichier main.tf Avoir les output à l’intérieur du fichier main.tf
rogerwelin/serverless-website-tutorial: Build a serverless website from scratch with Terraform and Go (github.com) Créez un site Web serverless avec Terraform et Go 2 contributeurs Oui car on voit qu’il y a un fichier pour les variables, pour output et un fichier main.tf Non
https://github.com/gbourniq/django-on-aws Application Web Django déployée sur AWS via des modèles Cloudformation, avec une approche d’infrastructure en tant que code suivant les meilleures pratiques de l’architecture AWS. L’application est un exemple de site Web de type blog qui peut être utilisé comme un portfolio personnel. - Oui, différents fichiers main.tf, variables.tf, output.tf et config.tf. En plus ils ont utilisé des modules Non
https://github.com/alammel/serverless-website Un projet Terraform pour créer un site Web serverless sur AWS cinquantaine de commits Pas mis à jour depuis 2018 Oui, il y a des fichier pour les ressources, les variables et un fichier providers.tf Non
https://github.com/xjantoth/aws-eks-devopsinuse Tutoriel utilisation de terraform pour un déploiement AWS une centaine de commits Contient un fichier main.tf, output.tf, variables.tf et autres Projet simpliste
https://github.com/mcarlton00/aws-auto-deploy-demo Code de démonstration pour une présentation : Déployer des services sur AWS sans quitter le confort de votre bureau Code de démo , douzaine de commits Respect des nommages Région de déploiement écrite en dur
https://github.com/michelderu/starship-enterprise Démo IOT avec Astra (Cassandra en tant que service de DataStax) et les fonctions Lambda serverless sur AWS. Utilise plusieurs technologies diversifiées Ils auraient pu faire un fichier output.tf pour mettre les output. Mais ici comme c’est petit projet ce n’est pas très grave. Ne contient pas de fichiers séparé pour les outputs ainsi que les variables
https://github.com/dnldxn/dixon.xyz Un site web personnel - Non, car les ressources sont directement dans le fichier main.tf Oui, pas de fichier resources.tf
https://github.com/Voronenko/wordpress-classic-app-demo Demo de déploiement d’un projet Wordpress Projet personnel ayant plusieurs branches Oui les fichiers de configuration et les variables par exemple sont hors du main.tf, ils y sont importé Non
https://github.com/combinatorist/terraform-demo Demo de déploiement sur AWS - Fichiers séparé pour pour la configuration AWS Pas de fichiers output / variables

Bonnes pratiques : Vérification automatique du code et test

Terraform permet d’écrire du code. Il est donc important de pouvoir tester ce code notamment parce qu’un mauvais code de déploiement peut être débité par le fournisseur Cloud et peut faire écrouler les services déployés. La question est donc de savoir si et comment on peut tester du code Terraform. Il existe des outils qui permettent de tester et vérifier le code Terraform.

Limite : Aucun trouvé

Limite : Nécessite Python3 afin d’installer Checkov sur une machine

Limite : Framework payant pour les grands projets.

Limite : On ne peut pas personnaliser les règles de scan de SonarQube

Nous avons lancé ces outils sur certains des projets que nous avons trouvé

Projets Résultats d’execution du checkov sur le dossier terrafom Résultat d’execution de deepsource
https://github.com/millieindeed/interview-static-site/tree/master 13 checks passés, 7 échoués et 0 ignoré 4 problèmes : “Bucket does not have logging enabled”, “Unencrypted S3 bucket”, “S3 Data should be versioned” et “S3 Bucket has an ACL defined which allows public access”
https://github.com/clburlison/clburlison.com/tree/master 21 checks ont passés, 15 checks ont échoués et 0 ignorés 1 problème important : “Potentially sensitive data stored in `default` value of variable”
rogerwelin/serverless-website-tutorial: Build a serverless website from scratch with Terraform and Go (github.com) 16 checks ont passés,18 checks ont échoués et 0 ignorés 1 problème : Function params involve heavy amount of copying””
https://github.com/gbourniq/django-on-aws 69 checks ont passés, 54 checks ont échoués, 1 erreur de parsing et 0 checks ignorés 3 problème de sécurité : “An inline ingress security group rule allows traffic from `/0`”, “An inline egress security group rule allows traffic to `/0`”, “`aws_instance` resource should activate session tokens for Instance Metadata Service”
https://github.com/alammel/serverless-website 96 checks ont passés, 26 checks échoués et 0 ignorés Ce projet a 16 issues et 13 anti patterns
https://github.com/xjantoth/aws-eks-devopsinuse 1 check passé, 0 échoués, 0 ignorés 0 problème
https://github.com/mcarlton00/aws-auto-deploy-demo 18 checks ont passés, 16 checks ont échoués et 0 ignorés 3 problèmes : “Undefined name detected”, “Re-defined variable from outer scope” et “Exception caught is very general”
https://github.com/michelderu/starship-enterprise 0 problème 0 problème
https://github.com/dnldxn/dixon.xyz 4 checks passés, 7 checks échoués et 0 ignorés Mêmes problème que le repository 1 (voir cellule k26)
https://github.com/Voronenko/wordpress-classic-app-demo 289 checks passés, 194 checks échoués et 0 ignorés 0 problèmes
https://github.com/combinatorist/terraform-demo 4 checks ont passés, 10 échoués et 0 ignorés 0 problèmes
https://github.com/brutalismbot/brutalismbot.com  0 problème 0 problèmes
https://github.com/gordonmurray/terraform_aws_rds_proxysql 49 checks passés, 14 checks ont échoués et 0 ignorés 0 problèmes
https://github.com/alejunio/terraform-ansible-aws-wordpress  9 checks ont passés, 8 checks ont échoués et 0 ignorés Trouvé 6 problèmes : “An inline egress security group rule allows traffic to `/0`”, “Potentially sensitive data stored in block attribute”, “An inline ingress security group rule allows traffic from `/0`”, “Potentially sensitive data stored in `default` value of variable” “`aws_instance` resource should activate session tokens for Instance Metadata Service” et “AWS provider has access credentials specified”
https://github.com/Dzhuneyt/hotelster 3 checks ont passés, 4 ont échoués 0 ignorés 1 problème : “`aws_instance` resource should activate session tokens for Instance Metadata Service”
https://github.com/HaberkornJonas/DevOps_T-NSA-700 16 checks ont passés, 16 checks ont échoués et 0 ignorés 1 problème de sécurité : “Detected password authentication instead of `SSH` keys”
https://github.com/Murph9/dash.murph9.com/blob/main/dash/site_contents/index.html 7 checks ont passés, 10 checks ont échoués et 0 ignorés 8 problèmes de sécurité : “CloudFront distribution should have Access Logging configured”, “CloudFront distribution uses outdated SSL/TLS protocols”, “S3 Bucket has an ACL defined which allows public access”, “S3 Bucket does not have logging enabled”, “Unencrypted S3 bucket”, “S3 Data should be versioned” et “CloudFront distribution does not have a WAF in front”
https://github.com/OlesYudin/demo_ci-cd 6 checks ont passés, 5 ont échoués et 0 ignorés 3 problème de sécurité : “`aws_instance` resource should activate session tokens for Instance Metadata Service”, “An inline ingress security group rule allows traffic from `/0`” et “An inline egress security group rule allows traffic to /0\

Bonnes pratiques : Utilisation des modules

Un module est un ensemble de fichiers de configurations réutilisables, comme des fonctions dans les langages de programmation. Un projet peut placer certaines configurations dans des dossiers et les appeler dans d’autres configurations. Terraform a aussi des registres (dépôts) de configurations publiques et privées pour partager et réutiliser des configurations dans la communauté ou dans des organisations. Les modules ont donc de très bonnes propriétés et leur utilisation est une bonne pratique Terraform.

Infrastructure as Code “Templatable”

Notre idée de départ sur les outils Infrastructure as Code, consistait partir du code source d’un projet n’étant pas encore déployé dans le Cloud afin de définir le code Terraform pour le déployer sur le fournisseur de Cloud de notre choix. Après quelques recherches sur le mode de fonctionnement de Terraform nous n’avions pas de pistes pour répondre à cette question. Lorsque nous avons découvert l’existence des modules au sein de Terraform nous avons alors décidé de réorienter la question. En effet vu que les modules permettent de factoriser du code qui accomplit des tâches répétables, nous nous sommes posé la question de comment un développeur peut savoir s’il peut utiliser des modules existants dans son code Terraform pour le simplifier et quels modules existants pourraient l’aider. Les modules publics de Terraform sont accessibles à partir de l’API REST de Terraform. Nous avons développé un script qui récupère les informations de tous les modules publics (dernières versions) sur Terraform. Nous avons ensuite récupéré pour chaque module existant les ressources utilisées par le module. Les ressources sont des éléments de base du langage Terraform qui permettent d’utiliser un élément particulier du fournisseur cloud. Les ressources sont spécifiques au fournisseur cloud. Nous avons écrit des fonctions qui nous permettent de récupérer les ressources utilisées dans un code utilisateur (on entend par là du code terraform qui déploie effectivement des applications). Nous comparons ensuite les ressources utilisées aux ressources de tous les modules recensés. Nous appliquons pour cela un bonus de similarité si une ressource est utilisée dans le code utilisateur et dans le module et un malus si une ressource est utilisée dans le module sans être dans le code utilisateur. L’idée étant que si l’utilisateur est en train d’écrire du code terraform qui fait quelque chose déjà implémenté dans un module existant il utilisera les mêmes ressources que le module. Nous allons montrer les résultats obtenus.

Projet Description Bonus de similarité Malus Modules similaires trouvés (score >0) Faux positifs
https://github.com/clburlison/clburlison.com Site web personnel déployé avec Terraform 3 1 tmknom/s3-lb-log/aws/2.0.0
GeminiWind/static-website/aws/1.0.0
JamesWoolfenden/cloudfront-compound/aws/0.0.41
rafaelmarques7/cfsw/aws/1.1.0
MagnetarIT/s3-website/aws/0.11.0
conortm/s3-static-website/aws/0.0.3
genstackio/layer-incoming/aws/0.1.5
hahuang65/s3-cloudfront/module/1.2.0
egarbi/static-site/aws/1.0.4
telia-oss/static-site/aws/3.1.0
sudoinclabs/sudo-cloudfront-website/aws/0.1.1
scaffoldly/public-website-distribution/aws/0.15.1
MagnetarIT/s3/aws/0.2.0
tmknom/s3-lb-log/aws/2.0.0
JamesWoolfenden/cloudfront-compound
genstackio/layer-incoming/
MagnetarIT/s3/aws/0.2.0
scaffoldly/public-website-distribution/aws/0.15.1
https://github.com/clburlison/clburlison.com Site web personnel déployé avec Terraform 1 1 egarbi/static-site/aws/1.0.4
scaffoldly/public-website-distribution/aws/0.15.1
MagnetarIT/s3/aws/0.2.0
MagnetarIT/s3/aws/0.2.0
scaffoldly/public-website-distribution/aws/0.15.1
https://github.com/dzhw/metadatamanagement/blob/development/terraform/load_balancer.tf Recherche de donnée pour des études et recherches universitaires, déploiement d’un load_balancer 1 1 devops4me/web-load-balancers/aws/1.0.0
egarbi/alb-per-host/aws/0.0.4
 
https://github.com/dzhw/metadatamanagement/blob/development/terraform/aws_chatbot.tf Recherche de donnée pour des études et recherches universitaires, lancement d’un message d’alerte sur slack     aws-ia/sns/aws/0.0.2
dubiety/sns-pagerduty/aws/1.0.0
hazelops/nat-gateway-traffic-alert/aws/1.0.4
 
https://github.com/Dzhuneyt/hotelster Gestion des hôtels et des réservations basée sur le Web 1 1 pavandesh/testterraform/aws/1.0.2
trung/ec2-instance-simple/aws/0.0.1
pavandesh/testterraform/aws/1.0.2

Dans le tableau précédent nous pouvons voir que notre outil retrouve les modules les plus proches du projet en question. Il est possible de faire varier les bonus et les malus pour essayer de faire varier le périmètre des résultats.

Limites de notre approche

Nous n’avons pas beaucoup de grands projets déployant des choses avec Terraform. La plupart des projets qui déploient des choses sont des démos, des tutoriels. Les projets ayant des ressources déclarées dans plusieurs fichiers sont compliqués à appréhender parce qu’il peut s’agir d’une même unité de fonctionnalité ou de beaucoup de fonctionnalités différentes. Nous n’exploitons que la présence des ressources mais pas leur nombre d’utilisations, ou les autres mots clés tels que les variables et les outputs.

Les faux positifs du tableau précédent sont basés sur la description fournie par les modules et les projets. Afin de confirmer s’ils sont effectivement des faux positifs ou non, il faudrait la validation des développeurs des projets analysés.

Conclusion

Notre question principale était assez ambitieuse. En effet, on souhaitait étudier la possibilité de générer du code Terraform en partant d’une application existante. Même si nous n’avons pas pu directement apporter des réponses à cette question nous avons néanmoins pu trouver des pistes pour répondre aux questions sur les bonnes pratiques et la “templatabilité” du code Terraform. Nous avons rencontré assez de difficulté sur le fait qu’il n’existe pas beaucoup de projets publics d’envergure déployés avec Terraform disponibles sur GitHub. La plupart des projets sont des tutoriels ou des modules.

Bibliographie

Code

Notre code se trouve ici.