Modules OpenTofu¶
Encapsuler et réutiliser des groupes de resources avec des modules.
Qu'est-ce qu'un module¶
Un module est un répertoire contenant des fichiers .tf qui forment une unite logique réutilisable. Tout répertoire avec des fichiers HCL est un module — votre projet racine est le "root module".
Structure d'un module¶
modules/
└── webserver/
├── main.tf # Resources
├── variables.tf # Inputs
├── outputs.tf # Outputs
└── README.md # Documentation
Exemple : module webserver¶
# modules/webserver/variables.tf
variable "name" {
type = string
description = "Nom du serveur"
}
variable "machine_type" {
type = string
default = "e2-medium"
}
variable "zone" {
type = string
default = "europe-west1-b"
}
# modules/webserver/main.tf
resource "google_compute_instance" "this" {
name = var.name
machine_type = var.machine_type
zone = var.zone
boot_disk {
initialize_params {
image = "debian-cloud/debian-12"
}
}
network_interface {
network = "default"
access_config {}
}
}
# modules/webserver/outputs.tf
output "ip" {
value = google_compute_instance.this.network_interface[0].access_config[0].nat_ip
}
output "name" {
value = google_compute_instance.this.name
}
Appeler le module¶
# main.tf (root module)
module "web_prod" {
source = "./modules/webserver"
name = "web-prod-01"
machine_type = "n2-standard-2"
zone = "europe-west1-b"
}
module "web_staging" {
source = "./modules/webserver"
name = "web-staging-01"
}
output "prod_ip" {
value = module.web_prod.ip
}
Sources de modules¶
| Source | Syntaxe | Usage |
|---|---|---|
| Chemin local | "./modules/webserver" | Modules dans le même projet |
| Git | "git::https://github.com/org/module.git" | Modules partages |
| Registry | "hashicorp/consul/aws" | Modules publics |
| GCS | "gcs::https://storage.googleapis.com/bucket/module.zip" | Registry prive GCS |
| S3 | "s3::https://bucket.s3.amazonaws.com/module.zip" | Registry prive S3 |
Versionning¶
Epingler les versions
Utilisez toujours un tag ou un commit SHA pour les modules distants. Ne pointez jamais vers main en production.
Composition de modules¶
module "network" {
source = "./modules/network"
# ...
}
module "webserver" {
source = "./modules/webserver"
network = module.network.vpc_id # Output d'un module → input d'un autre
}
for_each avec les modules¶
variable "servers" {
type = map(object({
machine_type = string
zone = string
}))
default = {
web-01 = { machine_type = "e2-medium", zone = "europe-west1-b" }
web-02 = { machine_type = "e2-medium", zone = "europe-west1-c" }
}
}
module "webservers" {
for_each = var.servers
source = "./modules/webserver"
name = each.key
machine_type = each.value.machine_type
zone = each.value.zone
}
Bonnes pratiques¶
Un module = une responsabilité
Un module doit faire une seule chose. Preferez des modules petits et composables a un module monolithique.