DevOps Elastic Hayway
Document

SUBSCRIBE TO GET FULL ACCESS TO THE E-BOOKS FOR FREE 🎁SUBSCRIBE NOW

Professional Dropdown with Icon

SUBSCRIBE NOW TO GET FREE ACCESS TO EBOOKS

TerraformLesson 18 / 246 min readUpdated September 13, 2026

ALB / ELB avec Terraform (provider 5.x)

À la fin de ce tutoriel, vous saurez distinguer CLB, ALB et NLB, déclarer aws_lb, aws_lb_target_group, aws_lb_listener et les security groups, comprendre l’exigence ≥ 2 AZ, configurer des health checks, et gérer un lab optionnel en ca-central-1 — Terraform ≥ 1.9, AWS provider ~> 5.0. Message clé : ALB facturé à l’heure — snippets + plan en priorité ; si apply, destroy immédiat.

Niveau : Intermédiaire · Temps estimé : 35–45 min (lecture) / +15–30 min si apply · Versions testées : Terraform 1.16.2 (série ≥ 1.9), AWS provider ~> 5.0 · Dernière vérification : 2026-09-10

Slug proposé : terraform-alb · Série : Terraform · Remplace / fusionne : #1674 (ELB ancien → ALB moderne)

Prérequis

  • Avoir suivi EBS (terraform-ebs) : lab minimal, tags, destroy obligatoire
  • Idéalement Workspaces (terraform-workspaces) et Variables (terraform-variables)
  • Terraform ≥ 1.9, AWS CLI v2, profil de lab (aws sts get-caller-identity OK)
  • Notions VPC / subnets multi-AZ (voir maillage VPC) ; Auto Scaling utile pour enregistrer des cibles saines en prod

Coût estimé : un ALB est facturé à l’heure (+ LCU) — pas Free Tier friendly. Recommandation P2 : validate / plan sans apply, ou apply très court puis destroy immédiat. Aucun secret dans le HCL / tfvars.

Auth sans secrets. AWS_PROFILE / SSO uniquement. Jamais d’access_key / secret_key dans le provider. Pas d’ARN ACM hardcodé : lab en HTTP:80 ; HTTPS = variable hors git.

Ce que nous allons construire

Lab terraform alb (ca-central-1) — optionnel / coût horaire
  ├── versions.tf / providers.tf  → TF ≥ 1.9, aws ~> 5.0, region ca-central-1
  ├── Étapes 1–4                  → CLB/ALB/NLB + aws_lb + TG + listener + HC
  ├── Snippets HCL                → SG, subnets ≥ 2 AZ, health_check
  ├── apply OPTIONNEL             → ALB facturé → destroy immédiat
  └── Checklist + erreurs + quiz

(Alt : « Terraform ALB : aws_lb, target group, listener, health checks multi-AZ — ca-central-1 ».)

Étape 1 — CLB vs ALB vs NLB (pourquoi ALB en 2026)

Le vocabulaire « ELB » prête encore à confusion : historiquement il désignait le Classic Load Balancer ; aujourd’hui AWS regroupe ALB, NLB et (legacy) CLB sous Elastic Load Balancing. Pour un site ou une API HTTP en 2026, aws_lb de type application est le choix par défaut. Le CLB (aws_elb) ne doit plus apparaître dans un design neuf — le post #1674 est fusionné ici pour cette raison.

Cas réel : une équipe migre une API monolithique vers path-based routing (/api vs /admin). L’ALB route par listener rules vers des target groups distincts, sans multiplier les IP publiques. Un NLB serait surdimensionné (et moins expressif en HTTP) pour ce besoin. Réservez le NLB au TCP brut, aux IP statiques ou à la latence extrême.

Piège prod / lab : un ALB idle reste facturé à l’heure + LCU dès sa création. D’où la consigne P2 : plan d’abord, apply seulement si vous enchaînez un destroy dans la même session.

Critère CLB (Classic) ALB (Application) NLB (Network)
Couche L4/L7 legacy L7 HTTP/HTTPS L4 TCP/UDP/TLS
Terraform aws_elb (legacy) aws_lb type = "application" aws_lb type = "network"
Routage Basique Path / host / headers IP / port, très haute perf
Cibles Instances Instance, IP, Lambda, ALB Instance, IP, ALB
Cas 2026 Éviter APIs, sites, microservices Gaming, IoT, TCP brut
Coût lab Horaire Horaire + LCU Horaire + LCU

Pourquoi ALB pour terraform alb en 2026 ?

  1. Le CLB (aws_elb) est historique : les nouveaux designs ciblent ALB ou NLB.
  2. La majorité des APIs et sites passent par HTTP/HTTPS → ALB (routage path/host).
  3. ASG, ECS et EKS documentent surtout aws_lb + target groups.
  4. Remplacer #1674 = clarifier le vocabulaire « ELB » vers ALB ELBv2 explicite.

Le NLB reste pertinent (TCP pur, IP statiques, latence) — hors scope de ce lab P2 HTTP. Vous pouvez y revenir après le maillage Autoscaling.

Étape 2 — Ressources : aws_lb, target group, listener, SG

Mémorisez la chaîne plutôt que chaque argument isolé : le listener expose un port ; le target group définit comment sonder et répartir ; le SG ALB filtre l’entrée ; le SG app n’accepte que le SG ALB. Terraform déclare ces objets séparément : un oubli d’attachment ou de règle SG se traduit souvent par des 502/503 « mystérieux » alors que le apply est vert.

Ressource Rôle
aws_security_group Ingress 80/443 vers l’ALB ; egress vers cibles
aws_lb LB application, subnets ≥ 2 AZ
aws_lb_target_group Pool de cibles + health_check
aws_lb_listener Port public → forward vers le TG

Chaîne : Client → Listener (SG ALB) → Target group → Cibles (SG app).

# versions.tf
terraform {
  required_version = ">= 1.9.0"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

# providers.tf
provider "aws" {
  region = "ca-central-1"
  # Auth : AWS_PROFILE / SSO — jamais de clés ici
}

# variables.tf
variable "project" {
  type        = string
  description = "Préfixe lab unique (sans secret)."
}

variable "vpc_id" {
  type        = string
  description = "VPC existant (défaut ou lab)."
}

variable "public_subnet_ids" {
  type        = list(string)
  description = "Au moins 2 subnets dans 2 AZ distinctes."
  validation {
    condition     = length(var.public_subnet_ids) >= 2
    error_message = "Un ALB exige au moins deux subnets (deux AZ)."
  }
}

Étape 3 — Subnets ≥ 2 AZ + security groups

L’exigence multi-AZ n’est pas cosmétique : l’API AWS refuse un ALB sur une seule AZ. Deux subnets dans la même AZ échouent aussi. En ca-central-1, prenez explicitement 1a et 1b (ou les IDs renvoyés par votre VPC lab). enable_deletion_protection = false en lab évite un destroy bloqué ; en prod, activez-le pour les LB critiques.

Ouvrir 0.0.0.0/0 sur le port 80 est acceptable pour un lab HTTP court. En prod, restreignez (CloudFront, préfixes connus) et basculez HTTPS avec un certificat ACM dans la même Region que l’ALB.

Un ALB refuse un seul subnet ou deux subnets dans la même AZ. En ca-central-1 : ca-central-1a et ca-central-1b.

# main.tf — SG + ALB (apply optionnel — coût horaire)
resource "aws_security_group" "alb" {
  name_prefix = "${var.project}-alb-"
  description = "Lab ALB ingress HTTP"
  vpc_id      = var.vpc_id

  ingress {
    description = "HTTP from Internet (lab only)"
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = {
    Name      = "${var.project}-alb-sg"
    ManagedBy = "terraform"
    Lab       = "terraform-alb"
  }
}

resource "aws_lb" "app" {
  name               = "${var.project}-alb"
  internal           = false
  load_balancer_type = "application"
  security_groups    = [aws_security_group.alb.id]
  subnets            = var.public_subnet_ids

  enable_deletion_protection = false # lab : sinon destroy bloqué

  tags = {
    Name      = "${var.project}-alb"
    ManagedBy = "terraform"
    Lab       = "terraform-alb"
    Region    = "ca-central-1"
  }
}

Points durs à retenir :

  1. subnets : liste ≥ 2 IDs d’AZ différentes — sinon erreur API au plan/apply.
  2. load_balancer_type = "application" : c’est l’ALB (pas le NLB).
  3. enable_deletion_protection = false en lab : sinon destroy bloqué.
  4. SG ALB ≠ SG des instances : en prod, ouvrez le port applicatif depuis le SG ALB seulement.
  5. name ALB : longueur et charset limités — gardez un préfixe project court.

Sans cibles attachées, l’ALB reste « idle » mais facturé dès la création. D’où le mode plan-only recommandé.

Étape 4 — Health checks + target group + listener

Un health check trop strict (path 404, matcher 200 alors que l’app renvoie 204, intervalle agressif) marque toutes les cibles unhealthy : l’ALB répond 503. Alignez path, port et code avec l’application avant d’accuser Terraform. Derrière un ASG, préférez l’enregistrement via target_group_arns / attachment ASG plutôt que des attachments d’instances figées.

Pour HTTPS, stockez certificate_arn en variable hors dépôt public. Ce lab reste en HTTP:80 pour limiter certificats, DNS et coûts annexes — ce n’est pas un modèle de prod final.

Le health check décide si une cible reçoit du trafic. Mauvaise config = 502/503.

resource "aws_lb_target_group" "http" {
  name        = "${var.project}-tg-http"
  port        = 80
  protocol    = "HTTP"
  vpc_id      = var.vpc_id
  target_type = "instance" # ou "ip" / "lambda"

  health_check {
    enabled             = true
    path                = "/health"
    protocol            = "HTTP"
    matcher             = "200"
    interval            = 30
    timeout             = 5
    healthy_threshold   = 2
    unhealthy_threshold = 3
  }

  tags = { Lab = "terraform-alb" }
}

resource "aws_lb_listener" "http" {
  load_balancer_arn = aws_lb.app.arn
  port              = 80
  protocol          = "HTTP"

  default_action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.http.arn
  }
}

# CONCEPTUEL — nécessite une EC2 / ASG
# resource "aws_lb_target_group_attachment" "demo" {
#   target_group_arn = aws_lb_target_group.http.arn
#   target_id        = aws_instance.app.id
#   port             = 80
# }

output "alb_dns_name" {
  description = "DNS public de l’ALB (si apply)."
  value       = aws_lb.app.dns_name
}
Paramètre HC Conseil
path Léger (/health, /)
matcher 200 ou 200-399
App Doit répondre sur le port du TG
Prod ASG target_group_arns / attachment ASG

En prod, ajoutez un listener HTTPS:443 avec certificate_arn (ACM même Region ca-central-1) et une règle de redirection 80→443. Pour le lab P2 : restez en HTTP afin d’éviter certificat, DNS et coûts annexes. Stockez tout ARN sensible en variable / SSM Parameter Store — jamais en clair dans un dépôt public.

Étape 5 — Lab optionnel ca-central-1 + destroy

Le mode A (validate/plan) prouve que le graphe compile sans créer de LB facturé. Le mode B n’a de sens que si vous regardez réellement le DNS ALB puis détruisez. Gardez le filet CLI elbv2 describe-load-balancers : un LB orphelin hors state Terraform continue de facturer.

Mode A — Recommandé : validate / plan (sans coût ALB)

mkdir -p ~/terraform-alb-lab && cd ~/terraform-alb-lab
# Collez versions.tf, providers.tf, variables.tf, main.tf (étapes 2–4)

export AWS_PROFILE=lab
export AWS_REGION=ca-central-1
PROJECT="votreprenom20260910"

VPC_ID=$(aws ec2 describe-vpcs --filters Name=isDefault,Values=true 
  --query 'Vpcs[0].VpcId' --output text --region ca-central-1)
# Deux subnet IDs d’AZ distinctes → liste HCL ["subnet-aaa","subnet-bbb"]

terraform init && terraform fmt && terraform validate
terraform plan 
  -var="project=${PROJECT}" 
  -var="vpc_id=${VPC_ID}" 
  -var='public_subnet_ids=["subnet-AAA","subnet-BBB"]'
# STOP ici pour éviter le coût horaire ALB

Mode B — Apply minimal puis destroy immédiat

Uniquement si vous acceptez quelques minutes de facturation ALB :

terraform apply -auto-approve 
  -var="project=${PROJECT}" 
  -var="vpc_id=${VPC_ID}" 
  -var='public_subnet_ids=["subnet-AAA","subnet-BBB"]'
terraform output

# Destroy IMMÉDIAT — ne laissez pas l’ALB « pour plus tard »
terraform destroy -auto-approve 
  -var="project=${PROJECT}" 
  -var="vpc_id=${VPC_ID}" 
  -var='public_subnet_ids=["subnet-AAA","subnet-BBB"]'
cd ~ && rm -rf ~/terraform-alb-lab

aws elbv2 describe-load-balancers --region ca-central-1 
  --query "LoadBalancers[?contains(LoadBalancerName, '${PROJECT}')]"
# Attendu : []

Étape 6 — Checklist

Avant de passer au tuto IAM ou Autoscaling, confirmez mentalement : type application, ≥ 2 AZ, TG + listener + HC cohérents, SG séparés, aucun ARN sensible en clair, destroy prévu. Cette checklist évite les « ALB de démo » oubliés le week-end.

  1. Distinguer CLB / ALB / NLB — ALB pour HTTP 2026.
  2. Déclarer aws_lb application + ≥ 2 subnets / AZ.
  3. Coupler TG + health_check + listener.
  4. Séparer SG ALB / SG cibles ; tags Lab=terraform-alb.
  5. Region ca-central-1, TF ≥ 1.9, provider ~> 5.0.
  6. Aucun secret / cert ARN en clair.
  7. Plan ou destroy immédiat — pas d’ALB idle.

Nettoyage

cd ~/terraform-alb-lab
terraform destroy -auto-approve 
  -var="project=${PROJECT}" 
  -var="vpc_id=${VPC_ID}" 
  -var='public_subnet_ids=["subnet-AAA","subnet-BBB"]'
cd ~ && rm -rf ~/terraform-alb-lab
# Filet : aws elbv2 describe-load-balancers --region ca-central-1
# + SG tagués Lab=terraform-alb

Erreurs fréquentes

Symptôme Cause Correction
Need at least two subnets / AZ 1 subnet ou 2 dans même AZ 2 subnets AZ distinctes (1a+1b)
Destroy refusé enable_deletion_protection = true false en lab, puis destroy
Cibles unhealthy Path/port/SG HC incorrects Aligner path ; SG ALB → cibles
503 Aucune cible / toutes unhealthy Attachment EC2/ASG ou revoir HC
HTTPS sans certificat certificate_arn manquant ACM ca-central-1 ; lab = HTTP:80
aws_elb vs aws_lb Docs #1674 / CLB Migrer vers aws_lb application
Facture surprise ALB laissé après lab Destroy + vérif CLI
Name invalide / trop long Préfixe excessif ≤ 32 car., charset ALB
Listener rules conflict Plusieurs default_action / priorités Une default_action claire ; rules numérotées
TG instance vs ip Mauvaise target_type pour Fargate/ECS ip pour awsvpc ; instance pour EC2 classique
Cross-zone désactivé sans le savoir Attribut LB / TG Vérifier cross-zone selon besoin de répartition

Quiz (3 questions)

1. Pour une API HTTP avec Terraform en 2026, quelle ressource ?

  • A. aws_elb (CLB)
  • B. aws_lb load_balancer_type = "application"
  • C. NLB obligatoire pour tout HTTP

2. Combien de subnets / AZ minimum pour un ALB ?

  • A. Un subnet suffit
  • B. Au moins deux subnets dans deux AZ
  • C. Quatre AZ obligatoires en ca-central-1

3. Après un lab terraform alb, action critique ?

  • A. Laisser l’ALB jusqu’au lendemain
  • B. terraform destroy immédiat + vérif CLI
  • C. Activer deletion protection et oublier le state

4. Pourquoi séparer SG ALB et SG des cibles ?

  • A. Obligation de nommage
  • B. Least privilege : l’app n’écoute que depuis l’ALB
  • C. Réduit le prix LCU

5. Un ALB sans cibles saines renvoie souvent ?

  • A. 200 systématique
  • B. 5xx / 503 côté client
  • C. Une redirection ACM automatique

Réponses : 1‑B · 2‑B · 3‑B · 4‑B · 5‑B

FAQ

Slug live terraform-elb vs fichier terraform-alb ? Le contenu canonique P2 parle ALB moderne (aws_lb). L’ancien libellé ELB est conservé pour le SEO/menu live, mais le HCL cible ELBv2 application — pas aws_elb.

Faut-il un ALB pour un seul conteneur de lab ? Souvent non. L’ALB brille dès que vous voulez HA multi-AZ, host/path routing ou un front unique devant un ASG. Pour un smoke test unique, une IP/DNS d’instance peut suffire (hors objectifs de ce tuto).

Quand passer au NLB ? TCP/UDP pur, perf extrême, IP statiques, ou intégration PrivateLink — pas pour remplacer un simple reverse proxy HTTP.

Pour aller plus loin

Maillage série Terraform (P2)

← Précédent EBS (terraform-ebs)
→ Suivant IAM (terraform-iam)
Aussi VPC (aws-vpc-sous-reseaux-igw) · Autoscaling (aws-auto-scaling-launch-template) · ALB AWS (aws-alb-equilibrage-charge)
Carte Overview · Install · Workflow · Blocks · Providers · Variables · Locals · State · Modules · Workspaces · Labs AWS

Retour parcours Terraform — hub de la série et leçons sœurs.

Share your love

Leave a Reply

Your email address will not be published. Required fields are marked *