Utiliser et développer des modules
Pourquoi réutiliser du code ?
Les modules permettent de partager du code et de le rendre réutilisable. Un module contient du code Terraform qui peut déclarer des blocs resource et des blocs data, ainsi que des variables locales. Un module accepte des variables en entrée et expose des outputs en sortie. On peut considérer que le concept de module dans Terraform se rapproche de celui des librairies dans les langages de programmation.
Au niveau d’une entreprise, un module permet de partager de bonnes pratiques, comme des règles de nommage ou des paramétrages particuliers par défaut. Les développeurs ou opérateurs utilisant les modules n’ont alors plus à se préoccuper de ces points. Utiliser des modules permet de s’assurer de la bonne conformité de l’infrastructure qui est déployée et de pouvoir construire rapidement des infrastructures complètes.
Les modules sont également versionnés. L’utilisation d’un module versionné va permettre de pouvoir facilement récupérer les mises à jour de code et les déployer sur de multiples projets sans avoir à copier-coller le code.
Les providers de service cloud fournissent souvent des modules implémentant leurs bonnes pratiques, ou des modules implémentant des éléments complets d’infrastructure....
Le root module
Le root module est le répertoire principal du code qui contient les fichiers .tf. Le code écrit dans le root module peut contenir des définitions de provider, des blocs resource et data, ainsi que des déclarations variable et output. Le root module peut aussi contenir des blocs module qui permettent d’utiliser un autre module.
C’est dans ce répertoire que sont exécutées les commandes terraform.
La structure d’un module
Un module Terraform est un répertoire contenant des fichiers .tf qui suivent une convention de nommage particulière. Cette convention n’est pas obligatoire en soi, mais elle permet de se repérer plus facilement quand on lit du code. Elle est suivie par la grande majorité des modules publiés sur GitHub ou le registry Terraform.
Cette convention suit des règles de nommage et d’organisation que nous avons déjà vues dans cet ouvrage.
Les variables doivent être déclarées dans un fichier nommé variables.tf. Les outputs doivent être déclarés dans un fichier nommé outputs.tf.
Il est recommandé que chacun des blocs variable ou output déclare une description. La description est souvent utilisée pour générer la documentation d’un module.
Un fichier main.tf est le point d’entrée du code. Il peut éventuellement être vide. Pour un module simple, qui ne déclare que quelques blocs resource ou data, l’ensemble du code peut être déclaré dans ce fichier. Pour un module plus complexe qui déclare de nombreux blocs de code, il est souvent préférable de séparer le code dans plusieurs fichiers.
Un fichier README ou README.md est également recommandé pour décrire le module, son fonctionnement et son utilisation....
Modules et providers
Un module ne déclare jamais de bloc provider. La déclaration des providers est la responsabilité du code appelant le module, le root module. Un module va uniquement déclarer les providers dont il a besoin, ainsi que les versions minimales et maximales éventuelles à l’aide du bloc required_providers.
Ces déclarations sont faites dans un fichier versions.tf. Voici un exemple d’un tel fichier déclarant une version de Terraform minimale de 1.7 ainsi qu’un provider Scaleway requis en version 2.40 :
terraform {
required_providers {
scaleway = {
source = "scaleway/scaleway"
version = "~> 2.40"
}
}
required_version = "> 1.7"
}
Utiliser des modules
Un bloc module permet d’importer et d’utiliser un module dans du code Terraform.
Un même module peut être appelé plusieurs fois dans le même code, ou dans des codes différents.
Lorsqu’un bloc module est ajouté au code source, il est nécessaire d’exécuter la commande terraform init. Cette commande, en plus de télécharger les différents providers, télécharge également le code source du module qui est référencé par le bloc.
1. Structure d’un bloc module
Les blocs module ont la structure suivante :
module "<NOM>" {
source = "<SOURCE>"
<ARGUMENT> = <EXPRESSION>
}
Le mot-clé module est suivi directement du nom qui lui est attribué. Ce nom, au même titre que les blocs resource ou data permet de référencer le module pour en récupérer les output.
Contrairement aux resource ou data, un module ne déclare pas directement de type. Un bloc module doit déclarer un attribut obligatoire source, qui permet d’indiquer où le code du module doit être récupéré.
Voici un exemple d’utilisation d’un module nommé s3-bucket, qui crée un bucket sur le cloud AWS :
module "s3_bucket" {
source = "terraform-aws-modules/s3-bucket/aws"
bucket = "my-s3-bucket"
acl = "private"
versioning = {
enabled = true
}
}
Cette utilisation du module s3-bucket initialise pas moins de trois ressources ! Le bucket, ses ACL (pour access-control list) et la configuration de son versionning sont en principe à configurer avec des blocs resource différents dans le provider AWS. Ici, ce module simplifie grandement le travail.
Le modules3-bucket déclare un argument source qui permet de récupérer le code du module, dans cet exemple, la source du module est sur le Terraform Registry. Le bloc déclare ensuite trois arguments. Ces arguments correspondent aux variables qui sont déclarées dans le code du module, et doivent en respecter...
Publier un module sur le registry Terraform
Développer un module consiste principalement à suivre la structure exposée en début de ce chapitre.
Une fois le module développé, il peut être publié sur le registry Terraform.
La première étape consiste à publier le code du module sur un repository hébergé sur GitHub. Le registry Terraform utilise GitHub comme source de données pour récupérer le code des modules, ainsi que leurs versions.
Pour pouvoir être publié sur le registry Terraform, le repository GitHub doit être nommé terraform-<PROVIDER>-<NAME>. Le repository doit également au moins comporter un tag au format X.Y.Z ou vX.Y.Z, permettant d’identifier la première version du module à publier.
Une fois à l’adresse https://registry.terraform.io, cliquer sur le bouton Sign-in ouvre une page d’authentification avec un lien qui redirige vers l’authentification de GitHub.
Cliquer sur le lien redirige vers la page d’autorisation de GitHub. Sur cette page, la liste des droits demandés est listée. Si vous êtes membre d’une ou plusieurs organisations GitHub, il est aussi possible d’autoriser les accès au code présent dans ces organisations.
Passé cette étape, l’utilisateur est redirigé vers...
Conclusion
Ce chapitre a présenté la manière d’utiliser des modules Terraform et celle d’écrire et publier des modules, pour pouvoir réutiliser du code.
L’utilisation de modules est un élément important de Terraform, composer l’infrastructure en briques réutilisables permet d’accélérer le développement et le déploiement de l’infrastructure.
Le chapitre suivant présente les éléments avancés du langage Terraform, la création de ressources multiples ou conditionnelles, des expressions avancées comme le for ou les blocs dynamiques. Il présente aussi les éléments permettant de sécuriser l’utilisation du code avec la validation des variables et comment marquer les données sensibles avec les outputs sensitives.