Featured image of post Terraform Associate #5 — Les modules

Terraform Associate #5 — Les modules

Cinquième module de ma préparation à la certification Terraform Associate : les modules

Nous en sommes à un peu plus de la moitié du learning path pour l’obtention de la certification Terraform Associate, après le module sur la configuration. Cinquième objectif de l’exam guide, “Interact with Terraform modules” : cet article couvre les sources de module, les inputs/outputs, la portée des variables et le versionning.

Qu’est-ce qu’un module

Un module est un ensemble de fichiers .tf regroupés dans un même répertoire. Chaque configuration Terraform a au moins un module : le module racine, celui dans lequel on lance terraform apply. Les modules qu’il appelle sont des modules enfants, et peuvent eux-mêmes en appeler d’autres.

Regrouper des ressources dans un module permet de les réutiliser, de les partager entre équipes et de simplifier la configuration racine.

Utilisation

module "consul" {
  source  = "hashicorp/consul/aws"
  version = "0.1.0"

  servers = 3
}
  • source est le seul argument obligatoire : il indique où trouver le code du module.
  • terraform init télécharge et met en cache tout module référencé par la configuration.
  • Les autres arguments du bloc (servers ici) correspondent aux variables d’input déclarées par le module.

Sources de module

L’argument source détermine où et comment Terraform va chercher le module :

  • Chemin local (./modules/consul) : pas de téléchargement, le module suit le cycle de vie du code parent. Ne supporte pas le versionning.
  • Terraform Registry (hashicorp/consul/aws, format <namespace>/<nom>/<provider>) : source la plus courante pour les modules publics ou privés.
  • GitHub / Git / HTTP (git::https://example.com/vpc.git) : utile pour des modules non publiés sur un registre.
  • Buckets S3 / GCS : pour des modules stockés en interne sans registre dédié.

Seules les sources de registre (public ou privé) supportent l’argument version.

Inputs et outputs

Un module communique avec l’extérieur via des variables d’input et des outputs, comme évoqué dans l’article précédent sur les variables & outputs.

# modules/vpc/variables.tf
variable "cidr_block" {
  type = string
}

# modules/vpc/outputs.tf
output "vpc_id" {
  value = aws_vpc.this.id
}
# racine
module "network" {
  source     = "./modules/vpc"
  cidr_block = "10.0.0.0/16"
}

resource "aws_subnet" "web" {
  vpc_id = module.network.vpc_id
}
  • Les inputs se passent comme des arguments du bloc module.
  • Les outputs se référencent avec module.<nom>.<output>.

Portée des variables

Une variable ou un local défini dans un module n’est pas automatiquement visible dans les autres modules, parent ou enfant : chaque module a sa propre portée. Pour faire transiter une valeur :

  • Du parent vers l’enfant : passer un input au bloc module.
  • De l’enfant vers le parent : déclarer un output dans l’enfant, puis le référencer via module.<nom>.<output>.
  • Entre deux modules enfants : faire remonter la valeur au parent via un output, puis la repasser en input à l’autre module.

Il n’existe pas de variable globale partagée implicitement entre modules.

Registre public de modules

Le Terraform Registry héberge des modules publics, identifiés par <NAMESPACE>/<NOM>/<PROVIDER> (ex. terraform-aws-modules/vpc/aws). Chaque module y expose sa documentation, ses inputs/outputs et l’historique de ses versions. Les modules verified sont validés par HashiCorp ou un partenaire.

Versionning des modules

Pour les sources de registre, l’argument version accepte des contraintes :

OpérateurEffet
= (ou rien)Version exacte
!=Exclut une version
>, >=, <, <=Comparaison
~>Autorise seulement le dernier composant à incrémenter (ex. ~> 2.1 autorise 2.1.x mais pas 2.2)
module "consul" {
  source  = "hashicorp/consul/aws"
  version = "~> 0.1"
}

Fixer une version évite qu’une mise à jour du module casse la configuration lors d’un prochain terraform init. Sans contrainte, Terraform utilise la dernière version disponible.

Ce que je retiens

  • Un module = un répertoire de fichiers .tf : la configuration racine est elle-même un module.
  • Seules les sources de registre supportent le versionning : un chemin local ou une source git suit le cycle de vie du code parent.
  • Pas de portée globale : toute communication entre modules passe explicitement par des inputs et des outputs.

Prochaine étape de la série : le state management.

Généré avec Hugo
Thème Stack conçu par Jimmy