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 22 / 244 min readUpdated September 13, 2026

Auto Scaling Terraform : Launch Template

À la fin de ce tutoriel, vous saurez pourquoi un Auto Scaling Group (ASG) est indispensable en production, pourquoi aws_launch_configuration est déprécié, et comment déclarer aws_launch_template + aws_autoscaling_group (min / desired / max, health check ELB ou EC2) avec un aperçu du lien ALB target group. Region ca-central-1, Terraform ≥ 1.9, AWS provider ~> 5.0. Message clé : terraform autoscaling moderne = Launch Template uniquement ; lab plan-only ou destroy immédiat (EC2 facturé).

Niveau : Intermédiaire · Temps estimé : 40–50 min (lecture) / +15–25 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-autoscaling · Série : Terraform · Remplace : #1719 — INTERDIT aws_launch_configuration (déprécié) ; utiliser aws_launch_template + aws_autoscaling_group

Prérequis

  • VPC (terraform-vpc) : subnets ≥ 2 AZ, SG, outputs publics / privés
  • Idéalement ALB (terraform-alb) : target group + health checks ; IAM (terraform-iam) : instance profile / rôle EC2
  • Terraform ≥ 1.9, AWS CLI v2, profil lab (aws sts get-caller-identity OK)
  • Notions EC2 / AMI / user-data (aws-ec2-ami-user-data, aws-auto-scaling-launch-template)

Coût estimé : chaque instance ASG = EC2 à l’heure (+ EBS). Recommandation P2 : validate / plan sans apply, ou apply très court (desired=1, t3.micro) puis destroy immédiat. Aucun secret dans le HCL / tfvars.

Auth sans secrets. AWS_PROFILE / SSO uniquement — jamais de clés dans le provider. Pas de mot de passe, clé SSH privée ou user_data avec secrets en clair.

Ce que nous allons construire

Lab terraform autoscaling (ca-central-1) — plan-only ou destroy immédiat
  ├── versions.tf / providers.tf  → TF ≥ 1.9, aws ~> 5.0, region ca-central-1
  ├── Étape LT vs LC              → INTERDIT aws_launch_configuration
  ├── aws_launch_template         → AMI data, instance_type, SG, user_data
  ├── aws_autoscaling_group       → min/desired/max, VPC zone, health_check
  ├── Aperçu ALB TG               → target_group_arns (lien terraform-alb)
  └── Lab plan / destroy · checklist · quiz

(Alt : « Terraform autoscaling : aws_launch_template + aws_autoscaling_group, min/desired/max, health check ELB — ca-central-1 ».)

Ce guide remplace le post WordPress #1719. Focus : terraform autoscaling avec Launch Template (provider 5.x), discipline coûts EC2, et pont vers ALB / Route 53.

Étape 1 — Pourquoi un Auto Scaling Group

En production, une seule EC2 derrière un DNS est un point de défaillance : maintenance AZ, kernel panic, ou simple pic de trafic saturent le service. L’Auto Scaling Group ne « scale » pas seulement : il maintient une capacité et remplace les instances déclarées unhealthy. Terraform décrit cette intention (min / desired / max) au lieu de cliquer dans la console.

Cas réel : une API de facturation reçoit un pic le 1er du mois. Sans ASG, vous surdimensionnez 24×7. Avec ASG + politiques (hors scope de ce lab), vous montez desired puis redescendez. Même en lab sans politiques de scaling, le groupe prépare le terrain pour l’ALB : les cibles apparaissent et disparaissent sans réécrire le listener.

Piège prod : laisser desired_capacity élevé après un test de charge. Chaque instance facture compute + EBS jusqu’au destroy ou à la politique de scale-in. Taguez Lab / Owner et alarmez Billing.

Une instance EC2 seule est un SPOF (panne AZ, pic de charge). Un ASG maintient une flotte à capacité cible et remplace les instances unhealthy.

Besoin Sans ASG Avec ASG
Haute dispo multi-AZ Manuelle, fragile Subnets ≥ 2 AZ, remplacement auto
Capacité count figé min / desired / max
Health Surveillance manuelle EC2 ou ELB health check
Déploiement Recréer l’instance Nouveau Launch Template + refresh
Coût lab 1 instance oubliée Même risque × N — destroy obligatoire

Règle P2 : l’ASG orchestre des instances saines derrière un TG. Chaîne : VPC multi-AZ → LT → ASG → (optionnel) ALB.

Étape 2 — Launch Template vs Launch Configuration (déprécié)

Les Launch Configurations appartiennent à l’ancienne génération Auto Scaling. AWS les a dépréciées : pas de versioning utile, support Spot/Mixed limité, et le provider Terraform 5.x oriente clairement vers aws_launch_template. Si vous ouvrez un vieux module ou le post #1719, migrez avant d’ajouter des features.

Le Launch Template versionné permet un déploiement progressif : vous publiez une nouvelle version AMI / user_data, puis un instance refresh de l’ASG. C’est le socle des rolling updates modernes — impossible proprement avec une LC immuable à recréer entièrement.

Critère Launch Configuration Launch Template
Ressource TF aws_launch_configuration aws_launch_template
Statut AWS Déprécié Recommandé / actuel
Versioning Non (immuable, à recréer) Versions LT ($Latest, $Default, numéro)
Spot / Mixed Instances Limité Oui (mixed_instances_policy)
Tags instance Partiels tag_specifications riches
Série P2 INTERDIT Obligatoire

Pourquoi interdire aws_launch_configuration : dépréciation AWS, pas de versioning utile, provider 5.x pousse aws_launch_template + aws_autoscaling_group, et #1719 doit être remplacé sans LC.

Message clé SEO : terraform autoscaling 2026 = Launch Template uniquement.

Étape 3 — Provider + aws_launch_template

La data source AMI évite de copier un ami-… d’une Region à l’autre. En ca-central-1, un filtre Amazon Linux 2023 + most_recent suffit pour le lab. Le user_data reste minimal et sans secrets : mots de passe, jetons CI ou clés privées n’ont rien à faire en clair dans le state.

En prod, branchez un instance profile IAM (terraform-iam) pour SSM Session Manager : plus besoin d’ouvrir SSH 22 depuis Internet. Les tag_specifications propagent Lab sur les instances lancées — indispensable pour le filet CLI de nettoyage.

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

provider "aws" {
  region = "ca-central-1" # AWS_PROFILE / SSO — jamais de clés
}

variable "project" { type = string }
variable "vpc_id" { type = string }
variable "private_subnet_ids" {
  type = list(string) # ≥ 2 AZ — sorties terraform-vpc
}
variable "app_sg_id" { type = string }
variable "instance_type" {
  type    = string
  default = "t3.micro" # lab : petit type
}
variable "desired_capacity" {
  type    = number
  default = 1 # lab : 1 ; prod souvent ≥ 2
}

data "aws_ami" "amazon_linux" {
  most_recent = true
  owners      = ["amazon"]
  filter {
    name   = "name"
    values = ["al2023-ami-*-x86_64"]
  }
}

resource "aws_launch_template" "app" {
  name_prefix   = "${var.project}-app-"
  image_id      = data.aws_ami.amazon_linux.id
  instance_type = var.instance_type

  vpc_security_group_ids = [var.app_sg_id]

  # Lab : user_data minimal (pas de secrets)
  user_data = base64encode(<<-EOT
    #!/bin/bash
    echo "ok" > /usr/share/nginx/html/health.txt || true
  EOT
  )

  tag_specifications {
    resource_type = "instance"
    tags = {
      Name = "${var.project}-asg-instance"
      Lab  = "terraform-autoscaling"
    }
  }

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

Points durs : data.aws_ami, name_prefix, user_data base64 sans secrets, tags Lab=terraform-autoscaling. Instance profile IAM : voir terraform-iam.

Étape 4 — aws_autoscaling_group : min / desired / max + health check

vpc_zone_identifier doit lister des subnets ≥ 2 AZ : sinon votre « HA » tient sur une seule salle. En lab, min_size = 0 permet de redescendre à zéro après test ; en prod, un min ≥ 2 (ou ≥ 1 multi-AZ selon le SLA) évite de servir à froid.

Le passage EC2 → ELB change la définition de « healthy » : l’ASG interroge le target group. Si votre application met 90 s à démarrer et que le grace period est à 30 s, vous obtiendrez une boucle de remplacements. Augmentez le grace period ou corrigez le chemin de health check avant de blâmer Terraform.

resource "aws_autoscaling_group" "app" {
  name                      = "${var.project}-asg"
  vpc_zone_identifier       = var.private_subnet_ids # ≥ 2 AZ
  min_size                  = 0
  desired_capacity          = var.desired_capacity
  max_size                  = 2
  health_check_type         = "EC2" # lab ; prod derrière ALB → "ELB"
  health_check_grace_period = 120

  launch_template {
    id      = aws_launch_template.app.id
    version = "$Latest"
  }

  tag {
    key                 = "Name"
    value               = "${var.project}-asg"
    propagate_at_launch = true
  }
  tag {
    key                 = "Lab"
    value               = "terraform-autoscaling"
    propagate_at_launch = true
  }

  lifecycle {
    create_before_destroy = true
  }
}

# INTERDIT en série P2 (déprécié) :
# resource "aws_launch_configuration" "legacy" { ... }
Paramètre Rôle lab P2 Prod typique
min_size 0 (économie) ≥ 2 (HA)
desired_capacity 1 Charge nominale
max_size 2 (plafond) Selon budget + alarmes
health_check_type EC2 ELB si ALB + TG
vpc_zone_identifier Subnets privés VPC Multi-AZ obligatoires

EC2 vs ELB : EC2 = status checks (lab sans ALB). ELB = santé du target group — requis derrière un ALB. Avec ELB, augmentez health_check_grace_period pour éviter les remplacements en boucle au boot.

Étape 5 — Lien ALB target group (aperçu)

Ne créez pas un second load balancer dans ce tuto : réutilisez le TG du guide ALB. L’attachement peut se faire via target_group_arns sur l’ASG ou aws_autoscaling_attachment. L’important est la cohérence SG : le port applicatif n’accepte que le SG de l’ALB, pas 0.0.0.0/0.

En prod, l’ALB (terraform-alb) reçoit le trafic ; le target group enregistre les instances de l’ASG.

# Aperçu — TG déjà créé dans terraform-alb (ne dupliquez pas le LB ici)
# variable "target_group_arn" { type = string }

# Dans aws_autoscaling_group.app, ajoutez :
#   target_group_arns    = [var.target_group_arn]
#   health_check_type    = "ELB"
#
# Alternative moderne (souvent préférée) :
# resource "aws_autoscaling_attachment" "app_tg" {
#   autoscaling_group_name = aws_autoscaling_group.app.name
#   lb_target_group_arn    = var.target_group_arn
# }

Chaîne : Client → Listener → TG → ASG (LT). SG app ← SG ALB seulement. Route 53 pointera vers l’ALB, pas l’ASG.

Étape 6 — Lab : plan-only ou destroy immédiat

Le mode plan-only suffit à valider LT + ASG sans facturer d’EC2. Si vous appliquez, gardez t3.micro et desired=1, chronométrez le destroy, puis vérifiez qu’aucune instance Lab=terraform-autoscaling ne reste running. Un ASG « vide » avec desired=0 peut encore exister : détruisez le groupe lui-même pour éviter les surprises lors d’un prochain scale-out manuel.

Mode A — Recommandé : validate / plan (quasi 0 €)

mkdir -p ~/terraform-asg-lab && cd ~/terraform-asg-lab
# Collez versions.tf, providers.tf, le LT + ASG (étapes 3–4)
# Récupérez vpc_id / private_subnet_ids / app_sg_id depuis terraform-vpc

export AWS_PROFILE=lab AWS_REGION=ca-central-1
PROJECT="votreprenom20260910"
terraform init && terraform fmt && terraform validate
terraform plan 
  -var="project=${PROJECT}" 
  -var="vpc_id=${VPC_ID}" 
  -var='private_subnet_ids=["subnet-AAA","subnet-BBB"]' 
  -var="app_sg_id=${APP_SG_ID}" 
  -var="desired_capacity=1"
# Attendu : 1 LT + 1 ASG — STOP ici en mode plan-only

Mode B — Apply minimal puis destroy immédiat

terraform apply -auto-approve 
  -var="project=${PROJECT}" 
  -var="vpc_id=${VPC_ID}" 
  -var='private_subnet_ids=["subnet-AAA","subnet-BBB"]' 
  -var="app_sg_id=${APP_SG_ID}" 
  -var="desired_capacity=1"

aws autoscaling describe-auto-scaling-groups --region ca-central-1 
  --query "AutoScalingGroups[?Tags[?Key=='Lab' && Value=='terraform-autoscaling']].AutoScalingGroupName"

terraform destroy -auto-approve 
  -var="project=${PROJECT}" 
  -var="vpc_id=${VPC_ID}" 
  -var='private_subnet_ids=["subnet-AAA","subnet-BBB"]' 
  -var="app_sg_id=${APP_SG_ID}" 
  -var="desired_capacity=1"
cd ~ && rm -rf ~/terraform-asg-lab

Discipline : desired=1 + t3.micro + destroy immédiat. Un ASG oublié facture chaque EC2 jusqu’au destroy.

Étape 7 — Checklist

  1. Comprendre pourquoi ASG (HA, capacité, remplacement unhealthy).
  2. INTERDIT aws_launch_configuration — uniquement aws_launch_template.
  3. Déclarer LT (AMI data, SG, tags) + ASG (min / desired / max).
  4. Choisir health_check_type EC2 (lab) ou ELB (derrière ALB).
  5. Subnets ≥ 2 AZ (terraform-vpc) ; aperçu target_group_arns.
  6. Region ca-central-1, TF ≥ 1.9, provider ~> 5.0, aucun secret.
  7. Plan-only ou destroy immédiat — pas d’EC2 / ASG idle.

Nettoyage

cd ~/terraform-asg-lab
terraform destroy -auto-approve 
  -var="project=${PROJECT}" 
  -var="vpc_id=${VPC_ID}" 
  -var='private_subnet_ids=["subnet-AAA","subnet-BBB"]' 
  -var="app_sg_id=${APP_SG_ID}" 
  -var="desired_capacity=1"
cd ~ && rm -rf ~/terraform-asg-lab

# Filet CLI
aws autoscaling describe-auto-scaling-groups --region ca-central-1 
  --query "AutoScalingGroups[?Tags[?Key=='Lab' && Value=='terraform-autoscaling']].AutoScalingGroupName"
aws ec2 describe-instances --region ca-central-1 
  --filters Name=tag:Lab,Values=terraform-autoscaling Name=instance-state-name,Values=running 
  --query 'Reservations[].Instances[].InstanceId'
# Attendu : []

Erreurs fréquentes

Symptôme Cause Correction
aws_launch_configuration dans le plan Contenu / module legacy #1719 Migrer vers aws_launch_template
ASG 0 instance / stuck Subnets 1 AZ, SG, AMI invalide ≥ 2 AZ ; AMI data ; SG OK
Remplacements en boucle health_check_type=ELB trop tôt Grace period ↑ ou lab en EC2
Cibles ALB unhealthy Path HC / port / SG ALB→app Aligner TG + SG (terraform-alb)
InvalidAMIID AMI hardcodée autre Region data.aws_ami en ca-central-1
Facture surprise ASG desired > 0 oublié Destroy + vérif CLI
CreateBeforeDestroy conflict Nom LT / ASG figé name_prefix sur le LT
IAM / SSM impossible Pas d’instance profile Brancher rôle (terraform-iam)
Mixed Instances / Spot KO Tentative via Launch Configuration Migrer LT + mixed_instances_policy
Instance refresh bloqué Mauvaise version LT / capacity Vérifier version LT et max ASG
Subnets publics par erreur Copie des outputs VPC Utiliser private_subnet_ids pour l’app

Quiz (3 questions)

1. Quelle ressource Launch est interdite en série P2 terraform autoscaling ?

  • A. aws_launch_template
  • B. aws_launch_configuration (déprécié)
  • C. aws_autoscaling_group

2. Pour un ASG derrière un ALB, quel health_check_type privilégier ?

  • A. Toujours EC2 uniquement
  • B. ELB (santé via target group)
  • C. Aucun health check en prod

3. Après un lab ASG avec desired=1, action critique ?

  • A. Laisser tourner jusqu’au lendemain
  • B. terraform destroy immédiat + vérif CLI
  • C. Monter max_size à 20 « au cas où »

4. Pourquoi name_prefix sur le Launch Template plutôt qu’un nom figé ?

  • A. Obligation AWS
  • B. Facilite create_before_destroy / rotations
  • C. Réduit le prix EC2

5. Que vérifie le health check ELB ?

  • A. Uniquement le status check EC2
  • B. La santé déclarée par le target group ALB
  • C. La facture Billing

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

FAQ

Faut-il encore apprendre aws_launch_configuration ? Non pour les nouveaux designs. Sachez le reconnaître dans du code legacy afin de le migrer, mais n’en créez plus.

desired_capacity vs politiques de scaling ? desired fixe la capacité courante. Les politiques (CPU, ALBRequestCount, schedules) modifient desired dans la fourchette min/max. Ce lab pose le socle ; les policies viennent ensuite.

Puis-je mettre l’ASG en subnets publics ? Techniquement oui, rarement souhaitable. Préférez privé + ALB public ; egress via NAT ou endpoints selon le budget.

Pour aller plus loin

Maillage série Terraform (P2)

← Précédent VPC (terraform-vpc)
→ Suivant Route 53 (terraform-route53)
Aussi ALB (terraform-alb) · IAM (terraform-iam) · ASG AWS (aws-auto-scaling-launch-template)
Carte Overview · … · IAM · RDS · VPC · Autoscaling · Route 53 · …

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 *