Comment créer un module Terraform dans les standards qualité Keltio

Comment créer un module Terraform dans les standards qualité Keltio

Publié le


Do not index
Do not index
Primary Keyword
Lié à Analyse sémantique (Articles liés) 1
Lié à Analyse sémantique (Articles liés)
Statut rédaction
Terminé
Lié à Analyse sémantique (Articles liés) 2

Introduction

💡
Commencer par lire le guide des bonnes pratiques en Terraform recommandées par Keltio ici :
Terraform est un outil créé par HashiCorp qui permet de gérer l'infrastructure en tant que code. Avec Terraform, les ressources cloud sont plus faciles à créer, gérer et détruire. Il existe certaines ressources souvent créées ensemble. Par exemple, un réseau privé virtuel (VPC) est fourni avec des sous-réseaux, des groupes de sécurité et une passerelle Internet facultative. Terraform vous permet de regrouper plusieurs ressources sous forme de module afin que vous puissiez le réutiliser.
Comme un projet Terraform, un module comporte généralement ces composants:
  • Fichier principal - les ressources fournies par le module
  • Variables d'entrée - permet aux utilisateurs de votre module de passer des valeurs d'entrée
  • Variables de sortie - permet aux utilisateurs de votre module d'obtenir des valeurs de sortie des ressources créées

0. Utiliser des modules communautaire existant

Avant de se lancer tête baisser dans la création d’un module Terraform qu’il faudra maintenir dans le temps, toujours penser à regarder s’il n’existe pas déjà ce que l’on souhaite sur le registry Terraform.
L’utilisation de module communautaire devra toutefois être vigilante sur le choix de contributeur non certifié sur la plateforme.
Des contributeurs natifs comme Azure, Microsoft, seront à privilégier.

1. Avoir un environnement de travail qui permet de code proprement

Chez Keltio nous installons un ensemble d’outils sur nos environnements de travail afin de pousser au maximum notre productivité et la qualité du code, c’est voici :

2. Utilisez un dépôt de contrôle de version

Si votre module peut être réutilisé dans différents projets, il doit être géré avec un dépôt de contrôle de version (Github, Gitlab,…). De plus, vous devriez envisager d'utiliser la versionnement sémantique pour gérer les versions du module afin que les nouvelles versions ne puissent pas casser les consommateurs de votre module.

3. Les fichiers à absolument créer dans le repo

README.md

Un code sans documentation, c’est un code qui ne vaut rien.
Chez Keltio, nous utilisons terrafom-docs pour générer la documentation automatiquement.
Pour ce faire, rien de plus simple, il suffit de créer un fichier nommé README.md et d’y glisser le contenu suivant :
# <LE NOM DU MODULE>

## Usage

```hcl-terraform
<UN EXEMPLE D'UTILISATION DU MODULE QUE VOUS AVEZ / ALLEZ CREER>
```

<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
Lors de la création de votre commit via le fichier .pre-commit-config.yaml (dont nous parlerons juste un peu plus tard), la documentation se mettra automatiquement à jour à chaque commit.

.terraform-docs.yml

Créer un fichier nommé : .terraform-docs.yml dans le dossier parent du module. Avec le contenu suivant :
version: ""

formatter: markdown

header-from: "main.tf"
footer-from: ""

sections:
  hide: []
  show: []

  hide-all: false # deprecated in v0.13.0, removed in v0.15.0
  show-all: true  # deprecated in v0.13.0, removed in v0.15.0

content: |-
  {{ .Header }}

  ## Usage

  ```hcl
  {{ include "examples/basic/main.tf" }}
  ```

  {{ .Inputs }}

  {{ .Outputs }}

output:
  file: ""
  mode: inject
  template: |-
    <!-- BEGIN_TF_DOCS -->
    {{ .Content }}
    <!-- END_TF_DOCS -->

output-values:
  enabled: false
  from: ""

sort:
  enabled: true
  by: name

settings:
  anchor: true
  color: true
  default: true
  description: false
  escape: true
  html: true
  indent: 2
  lockfile: true
  required: true
  sensitive: true
  type: true
Remarques :
  • Bien penser à changer "examples/basic/main.tf" par le nom réel du fichier d’exemple.
De cette façon le code de l’exemple sera positionné dans le readme et les utilisateurs pourront comprendre et réutiliser plus facilement le module.

.gitignore

A son lancement terraform va générer un ensemble de fichier que l’on ne souhaite absolument pas mettre dans les repos. Nous allons donc créer un fichier .gitignore avec le contenu suivant :
.terraform*
terraform.tfstate*

. versions.tf

Terraform évoluant vite ainsi que ses versions. Il est important de spécifier les versions de toutes les dépendances du module (provider et langage).
Il faut donc créer un fichier nommé versions.tf qui contient la version de terraform et la définition des providers, comme ceci :
terraform {
  # Exemple de compatibilité avec terraform (toutes les versions au dessus de la 0.13.0)
  required_version = ">= 0.13.0"

  # Exemples de providers
  # A noter que la source et la contrainte de version doit être spécifié
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = ">= 2.0"
    }
    gandi = {
      source  = "psychopenguin/gandi"
      version = "2.0.0-rc3"
    }
    null = {
      source  = "hashicorp/null"
      version = ">= 2.0"
    }
  }
}

variables.tf

La qualité d’un module s'évalue sur sa facilité d’utilisation mais aussi sur sa capacité de configuration. En terraform il existe souvent une quantité importante de variables pour chaque ressource.
Il est donc important d’ajouter au maximum de variables. De cette façon le module sera très configurable.
Dans un même temps, trop de variable cela apporte de la complexité, c’est pourquoi pour les variables moins fréquentes d’utilisation il est grandement recommandé de mettre des valeurs par défault.

outputs.tf

Combien de fois on a souhaité récupérer une donnée d’un module, mais celui n’avait pas l’output dont on avait besoin ?!!
De la même façon que les variables, il est important de définir un maximum d’outputs dans le fichier outputs. De cette façon, il sera plus facile pour la personne qui utilisera le module de l’interconnecter avec le reste de son infrastructure.
Dans le cas où les outputs contiennent des données sensibles, il ne faut pas oublier d’ajouter l’option sensitive = true sinon les données seront affichées en clair dans les logs d’exécution.

Dossier d’exemples

Comme tout code, même avec une bonne documentation, il peut être compliqué de comprendre et de réutiliser le code. C’est pourquoi chaque module doit comporter un dossier examples dans lequel il faudra mettre un ou plusieurs exemples d’utilisation du module.
Les exemples doivent :
  • Etre complet : Provider, variables, dépendances, versions.
  • Etre multiple si le module est complexe et / ou comporte beaucoup de variable.
  • Etre totalement fonctionnel : Si un terraform init et terraform apply ne suffit pas pour lancer l’exemple, alors cet exemple n’est pas fonctionnel.
  • Documenter les prérequis en terme de variable d’environnement via des commentaires dans le fichier main.tf de l'exemple.

4. Intégrez la sécurité et la qualité dans votre flux de travail by design

L'intégration d’outils de scan de qualité et sécurité sur votre infrastructure-as-a-code est une obligation si vous souhaitez mettre en place des standards haut en terme de qualité et de sécurité
 
Voici quelques outils intéressant à connaitre :
Pour mettre en place pour analyser la sécurité la configuration d’infrastructure mise en place dans votre code :
  • tfsec
  • Bridgecrew
  • Checkov
Pour valider le format et la qualité de votre code :
  • tflint
  • terraform validate
  • terraform fmt
 
Ces outils peuvent être exécutés localement après chaque commit git, ou exécutés dans des flux CI/CD.
Créer un fichier nommé : .pre-commit-config.yaml dans le dossier parent du module. Avec le contenu suivant :
fail_fast: false

repos:
- repo: https://gitlab.com/keltiotechnology/terraform/terraform-utils
  rev: "v0.1"
  hooks:
  - id: terraform-validate
  - id: tflint
  - id: terraform_fmt
  - id: terraform_docs
  - id: markdown-link-check
Initialiser le git hook de pre-commit en tapant la commande suivante (si vous n’avez pas pre-commit d’installé sur votre pc, il faudra l’installer en suivant ce tutoriel):
pre-commit install
De cette façon lors du commit, ce fichier sera utile pour :
  • Vérifier que le code est bien fonctionnel
  • Vérifier si le code possède des problèmes d'écriture
  • Formater et indenter le code
  • Créer le fichier de documentation du module
  • Vérifier les liens morts dans la documentation

4. Soyez cohérent dans la structure du module

Les fichiers du module doivent suivre le même format afin que chaque nouveau membre puisse comprendre. Cela est également utile lors de la maintenance du module.

5. Gardez votre module plat

Chaque module doit avoir une structure plate. Si le module a besoin d'entrées externes, envisagez d'appliquer l'injection de dépendance. Cela aidera le projet à être moins sujet aux erreurs si des modifications sont apportées.

6. Rendez votre module plus lisible

Bien que ce ne soit pas nécessaire, chaque module devrait avoir ces fichiers :
  • Readme : Permet aux consommateurs du module de comprendre les objectifs du module
  • Changelog : Pour dire quel type de modifications ont été apportées après chaque version
  • Exemples : Pour dire aux consommateurs du module comment utiliser le module

Quelles sont les pièges à éviter ?

Maintenir un module Terraform peut être coûteux. Avant de créer un module, vous devriez vous demander :
  • Est-il nécessaire de créer un module ?
  • Quelle valeur obtenez vous du module ?
  • Combien de ressources le module doit-il créer ? Un super module fournira beaucoup de ressources mais le rendra plus difficile à maintenir dans le temps.
Autres remarques
  • Afin d’assurer une modularité parfaite et éviter les sides effects, il ne faut pas ajouter les providers dans les modules.
  • On ne set jamais de backend dans un module.
  • Le nom des ressources dans un module ne doivent pas contenir de nom de client ou autre (toujours rester agnostique)
  • Les fichiers tfvars ne doivent être présent que dans le dossier exemples
  • UN MODULE NE PEUT PAS ETRE VALIDE S’IL N’A JAMAIS ÉTÉ APPLY AU MOINS UN FOIS

Conclusions

Dans cet article, nous discutons de la façon de créer un bon module Terraform. Bien qu'il n'y ait pas de règle d'or pour créer un bon module, gardez à l'esprit qu'un bon module Terraform est facile à utiliser, à maintenir et à respecter les normes de sécurité.
 

S'inscrire à la newsletter DevSecOps Keltio

Pour recevoir tous les mois des articles d'expertise du domaine

S'inscrire

Écrit par

Kévin Didelot
Kévin Didelot

Kévin est notre super expert DevSecOps et le fondateur de Keltio 👨🏻‍💻