Aller au contenu

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

module "vpc" {
  source  = "git::https://github.com/org/tf-module-vpc.git?ref=v1.2.0"
}

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.

Documenter les inputs/outputs

Chaque variable et output doit avoir une description. Utilisez terraform-docs pour générer automatiquement la documentation :

terraform-docs markdown table ./modules/webserver > modules/webserver/README.md