Un module est un ensemble de fichiers Terraform dans un répertoire. Ils permettent d’encapsuler et réutiliser de l’infrastructure.
Appeler un module (bloc module)
module "NOM" {
source = "CHEMIN_OU_REGISTRY"
version = "~> X.Y" # obligatoire pour le registry public
# Inputs du module (correspondent aux variables du module)
variable_1 = valeur_1
variable_2 = valeur_2
}Types de sources :
# Module local (chemin relatif)
module "vpc" {
source = "./modules/vpc"
}
# Registry public Terraform (registry.terraform.io)
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "~> 5.0"
}
# GitHub
module "vpc" {
source = "github.com/terraform-aws-modules/terraform-aws-vpc"
}
# Sous-dossier d'un repo Git
module "vpc" {
source = "git::https://github.com/org/repo.git//modules/vpc?ref=v2.0"
}
# Registry Terraform Enterprise / privé
module "vpc" {
source = "app.terraform.io/mon-org/vpc/aws"
version = "~> 1.0"
}Accéder aux outputs d’un module
module "vpc" {
source = "./modules/vpc"
cidr = "10.0.0.0/16"
}
resource "aws_instance" "web" {
subnet_id = module.vpc.private_subnet_ids[0] # ← module.NOM.OUTPUT
vpc_security_group_ids = [module.vpc.sg_id]
}Passer des variables entre modules
module "database" {
source = "./modules/rds"
vpc_id = module.vpc.vpc_id # output du module vpc
subnet_ids = module.vpc.private_subnet_ids # output du module vpc
env = var.env # variable racine
}
module "application" {
source = "./modules/ecs"
db_endpoint = module.database.endpoint # output du module database
db_password = module.database.password
}Créer un module
Structure d’un module :
modules/vpc/
├── main.tf ← ressources (aws_vpc, aws_subnet, etc.)
├── variables.tf ← inputs du module
├── outputs.tf ← ce que le module expose
├── versions.tf ← required_providers (optionnel)
└── README.md ← documentation (recommandé)
variables.tf (inputs) :
variable "vpc_cidr" {
description = "CIDR block du VPC"
type = string
default = "10.0.0.0/16"
}
variable "env" {
description = "Environnement"
type = string
validation {
condition = contains(["dev","staging","prod"], var.env)
error_message = "Environnement invalide."
}
}
variable "availability_zones" {
description = "Liste des AZs"
type = list(string)
}main.tf :
resource "aws_vpc" "this" {
cidr_block = var.vpc_cidr
tags = {
Name = "vpc-${var.env}"
Environment = var.env
}
}
resource "aws_subnet" "private" {
for_each = toset(var.availability_zones)
vpc_id = aws_vpc.this.id
availability_zone = each.value
cidr_block = cidrsubnet(var.vpc_cidr, 8, index(var.availability_zones, each.value))
}outputs.tf :
output "vpc_id" {
description = "ID du VPC créé"
value = aws_vpc.this.id
}
output "private_subnet_ids" {
description = "IDs des subnets privés"
value = [for s in aws_subnet.private : s.id]
}
output "vpc_cidr" {
description = "CIDR du VPC"
value = aws_vpc.this.cidr_block
}Meta-arguments disponibles dans module
module "servers" {
source = "./modules/server"
# count
count = var.env == "prod" ? 3 : 1
# for_each
for_each = var.regions
region = each.value
# depends_on
depends_on = [module.networking]
# providers (passer un provider aliasé au module)
providers = {
aws = aws.us-east
}
}Module Registry public — bonnes pratiques
# Utiliser des modules maintenus par la communauté
module "eks" {
source = "terraform-aws-modules/eks/aws"
version = "~> 20.0" # ← toujours épingler la version
cluster_name = "mon-cluster"
cluster_version = "1.29"
vpc_id = module.vpc.vpc_id
subnet_ids = module.vpc.private_subnet_ids
}
module "rds" {
source = "terraform-aws-modules/rds/aws"
version = "~> 6.0"
identifier = "ma-bdd"
engine = "postgres"
...
}En relation avec
- HCL — Vue d’ensemble — hub syntaxe HCL
- Blocs fondamentaux — bloc
moduleetvariable/outputdans les modules - Meta-arguments — count, for_each, depends_on dans les modules
- terraform get — télécharger les modules
- terraform init — init télécharge les modules automatiquement