Passer au contenu principal

Organisation (Terraform)

Les modules

Un projet Terraform sans modules est un script. Avec des modules bien conçus, c'est une bibliothèque d'infrastructure réutilisable entre projets, entre environnements, et entre équipes. Les modules sont l'équivalent des fonctions en programmation : encapsulation, interface claire, réutilisabilité.

Structure d'un module

modules/
└── vpc/
    ├── main.tf          # ressources du module
    ├── variables.tf     # inputs du module
    ├── outputs.tf       # outputs exposés
    ├── versions.tf      # contraintes de versions
    └── README.md        # documentation

Écrire un module

# modules/vpc/variables.tf
variable "name" {
  type        = string
  description = "Nom du VPC"
}

variable "cidr_block" {
  type        = string
  description = "Bloc CIDR du VPC"
  default     = "10.0.0.0/16"
}

variable "public_subnet_count" {
  type    = number
  default = 2
}

# modules/vpc/main.tf
resource "aws_vpc" "this" {
  cidr_block           = var.cidr_block
  enable_dns_hostnames = true
  tags = { Name = var.name }
}

resource "aws_subnet" "public" {
  count             = var.public_subnet_count
  vpc_id            = aws_vpc.this.id
  cidr_block        = cidrsubnet(var.cidr_block, 8, count.index)
  availability_zone = data.aws_availability_zones.available.names[count.index]
  tags = { Name = "${var.name}-public-${count.index}" }
}

# modules/vpc/outputs.tf
output "vpc_id" {
  value = aws_vpc.this.id
}

output "public_subnet_ids" {
  value = aws_subnet.public[*].id
}

Appeler un module

# main.tf (racine du projet)
module "vpc_prod" {
  source = "./modules/vpc"    # chemin local

  name                = "prod-vpc"
  cidr_block          = "10.0.0.0/16"
  public_subnet_count = 3
}

module "vpc_staging" {
  source = "./modules/vpc"

  name       = "staging-vpc"
  cidr_block = "10.1.0.0/16"
}

# Utiliser les outputs du module
resource "aws_instance" "web" {
  subnet_id = module.vpc_prod.public_subnet_ids[0]
}

Sources de modules

# Chemin local
source = "./modules/vpc"

# Terraform Registry
source  = "terraform-aws-modules/vpc/aws"
version = "~> 5.0"

# Git
source = "git::https://github.com/org/terraform-modules.git//vpc?ref=v1.2.0"

# GitHub (shorthand)
source = "github.com/org/terraform-modules//vpc"

# S3
source = "s3::https://s3.amazonaws.com/mon-bucket/modules/vpc.zip"

Registry public : modules prêts à l'emploi

# Module VPC AWS officiel
module "vpc" {
  source  = "terraform-aws-modules/vpc/aws"
  version = "~> 5.0"

  name = "mon-vpc"
  cidr = "10.0.0.0/16"

  azs             = ["eu-west-1a", "eu-west-1b", "eu-west-1c"]
  private_subnets = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]
  public_subnets  = ["10.0.101.0/24", "10.0.102.0/24", "10.0.103.0/24"]

  enable_nat_gateway = true
}
# Télécharger les modules après modification des sources
terraform init