Dernière révision : mai 2026
Configurez les services AWS figurant à l'examen SAA-C03 avec Terraform simple — un bloc à la fois, chacun étant lié à un domaine de l'examen. Le même code fonctionne sur OpenTofu.
À la fin de ce lab, vous aurez provisionné, avec du Terraform simple, une pile web haute disponibilité multi-AZ typique — un VPC personnalisé avec des sous-réseaux publics et privés répartis sur deux AZ, un équilibreur de charge d'application (ALB) accessible via Internet, un groupe Auto Scaling d'instances EC2 dans la couche privée, et une base de données RDS multi-AZ pour que l'application puisse communiquer. Cinq piliers de l'examen en cinq étapes.
Chaque ressource utilise du Terraform simple — le même code fonctionne sans modification sur OpenTofu. Pas de variables, pas de modules, pas d'état distant. Insérez les extraits dans un seul fichier main.tf, exécutez terraform init une fois, puis terraform apply étape par étape.
>= 1.5 ou OpenTofu >= 1.6.us-east-1 (région par défaut pour ce lab — choisissez ce que vous voulez, mais la recherche d'AMI à l'Étape 3 suppose que la région dispose d'Amazon Linux 2023).skip_final_snapshot = true donc la destruction est propre — n'utilisez jamais ce paramètre en production.La plupart de ce lab est éligible au niveau gratuit ou s'en approche : le VPC, l'ALB, l'ASG, les groupes de sécurité, IAM et la surveillance CloudWatch sont gratuits. Les deux éléments qui facturent même à l'arrêt :
Si vous êtes sensible aux coûts, définissez db_instance.multi_az = false pour le lab et consultez la documentation Multi-AZ séparément. L'examen récompense toujours la connaissance de l'attribut même si vous n'exécutez pas le modèle HA complet. Détruisez tout une fois terminé.
Nous fixons le fournisseur AWS ~> 5.60 et choisissons us-east-1 (toute région avec au moins deux AZ fonctionne). Le bloc data récupère la liste des AZ disponibles au moment de la planification — coder en dur les noms d'AZ comme us-east-1a est un anti-modèle SAA-C03 car le mappage nom d'AZ vers zone physique est spécifique à chaque compte (votre us-east-1a peut être une AZ physique différente de la mienne).
Toutes les ressources que nous créons en aval sont étiquetées avec un nom de projet unique via default_tags — Cost Explorer et les règles AWS Config fonctionnent tous deux avec les tags, et l'examen s'attend à ce que vous étiquetiez tout.
terraform {
required_version = ">= 1.5"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.60"
}
}
}
provider "aws" {
region = "us-east-1"
default_tags {
tags = {
Project = "certlabpro-saa-c03"
ManagedBy = "terraform"
}
}
}
data "aws_availability_zones" "available" {
state = "available"
}Toute question de haute disponibilité du SAA-C03 suppose que vous répartirez la charge de travail sur au moins deux zones de disponibilité. Nous créons un VPC en /16 et y découpons quatre sous-réseaux en /20 — deux publics (pour l'ALB), deux privés (pour les instances EC2 et RDS). La passerelle Internet s'attache au VPC ; la table de routage publique y envoie 0.0.0.0/0.
Les sous-réseaux privés n'ont délibérément PAS de passerelle NAT dans ce lab — les passerelles NAT facturent environ 32 $/mois à l'arrêt (par AZ) et le SAA-C03 teste explicitement ce compromis dans les questions de coût. Si votre application avait besoin d'un accès Internet sortant depuis des sous-réseaux privés en production, vous ajouteriez une passerelle NAT (ou une instance NAT, l'alternative moins chère du SAA-C03).
Le VPC + sous-réseaux + IGW + table de routage de cette étape sont la base de tout ce qui suit — l'ALB se connecte aux sous-réseaux publics, les instances de l'ASG résident dans les sous-réseaux privés, et le groupe de sous-réseaux RDS à l'Étape 5 couvre les deux AZ privées.
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
enable_dns_hostnames = true
tags = { Name = "certlabpro-saa-c03-vpc" }
}
resource "aws_subnet" "public" {
count = 2
vpc_id = aws_vpc.main.id
cidr_block = "10.0.${count.index}.0/24"
availability_zone = data.aws_availability_zones.available.names[count.index]
map_public_ip_on_launch = true
tags = { Name = "certlabpro-saa-c03-public-${count.index}" }
}
resource "aws_subnet" "private" {
count = 2
vpc_id = aws_vpc.main.id
cidr_block = "10.0.${count.index + 10}.0/24"
availability_zone = data.aws_availability_zones.available.names[count.index]
tags = { Name = "certlabpro-saa-c03-private-${count.index}" }
}
resource "aws_internet_gateway" "main" {
vpc_id = aws_vpc.main.id
}
resource "aws_route_table" "public" {
vpc_id = aws_vpc.main.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.main.id
}
}
resource "aws_route_table_association" "public" {
count = 2
subnet_id = aws_subnet.public[count.index].id
route_table_id = aws_route_table.public.id
}Un Application Load Balancer est l'équilibreur de charge que le SAA-C03 s'attend à ce que vous utilisiez chaque fois que la question mentionne "HTTP / HTTPS" ou "routage basé sur le chemin" ou "cibler un service spécifique". Les Network Load Balancers gèrent TCP/UDP et l'ultra-faible latence ; Classic est obsolète. L'ALB est la solution.
L'ALB réside dans les deux sous-réseaux publics de l'Étape 2 — c'est ce que signifie "multi-AZ" structurellement. Son groupe de sécurité accepte le trafic HTTP (port 80) de n'importe où ; le groupe cible obtiendra ses membres du groupe ASG que nous créerons à l'Étape 4. La vérification de santé est le contrat entre l'ALB et la cible — si / retourne un code autre que 200, l'ALB arrête d'envoyer du trafic à cette instance.
Pas de HTTPS dans ce lab — cela nécessite un certificat ACM et un nom DNS, ce qui représente deux services supplémentaires dont nous n'avons pas besoin pour rendre le modèle HA visible. Ajoutez ACM en production.
resource "aws_security_group" "alb" {
name = "certlabpro-saa-c03-alb"
description = "ALB ingress on port 80 from the internet"
vpc_id = aws_vpc.main.id
ingress {
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"]
}
}
resource "aws_lb" "web" {
name = "certlabpro-saa-c03-alb"
load_balancer_type = "application"
internal = false
subnets = aws_subnet.public[*].id
security_groups = [aws_security_group.alb.id]
}
resource "aws_lb_target_group" "web" {
name = "certlabpro-saa-c03-tg"
port = 80
protocol = "HTTP"
target_type = "instance"
vpc_id = aws_vpc.main.id
health_check {
path = "/"
matcher = "200-299"
interval = 30
timeout = 5
healthy_threshold = 2
unhealthy_threshold = 3
}
}
resource "aws_lb_listener" "http" {
load_balancer_arn = aws_lb.web.arn
port = 80
protocol = "HTTP"
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.web.arn
}
}L'Auto Scaling est le pilier "élasticité" d'AWS Well-Architected et le deuxième sujet le plus testé sur le SAA-C03 après le Multi-AZ. Combiné avec l'ALB de l'Étape 3, un ASG vous offre à la fois la tolérance aux pannes (instances remplacées lorsqu'elles échouent) et la scalabilité (le nombre d'instances suit la demande) — les deux résultats sur lesquels le SAA-C03 pose constamment des questions.
Le modèle de lancement définit l'apparence de chaque nouvelle instance. Nous utilisons la dernière AMI Amazon Linux 2023, une t3.micro, le groupe de sécurité (équivalent à celui de l'Étape 2) qui accepte le trafic uniquement du groupe de sécurité de l'ALB (principe du moindre privilège au niveau réseau), et des données utilisateur minimales qui démarrent Nginx pour que la vérification de santé réussisse.
L'ASG relie trois éléments : où les instances s'exécutent (vpc_zone_identifier = nos sous-réseaux privés, les deux AZ), combien d'instances doivent exister (min_size = 2, max_size = 4 — deux pour la haute disponibilité, marge pour la scalabilité), et comment les nouvelles instances rejoignent l'équilibreur de charge (target_group_arns). Lorsque l'ASG lance une instance, elle est automatiquement enregistrée auprès du groupe cible de l'Étape 3.
resource "aws_security_group" "app" {
name = "certlabpro-saa-c03-app"
description = "App instances accept traffic only from the ALB SG"
vpc_id = aws_vpc.main.id
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
security_groups = [aws_security_group.alb.id]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
data "aws_ami" "al2023" {
most_recent = true
owners = ["amazon"]
filter {
name = "name"
values = ["al2023-ami-*-kernel-6.1-x86_64"]
}
}
resource "aws_launch_template" "app" {
name_prefix = "certlabpro-saa-c03-app-"
image_id = data.aws_ami.al2023.id
instance_type = "t3.micro"
vpc_security_group_ids = [aws_security_group.app.id]
metadata_options {
http_tokens = "required"
}
user_data = base64encode(<<-EOT
#!/bin/bash
dnf install -y nginx
systemctl enable --now nginx
EOT
)
}
resource "aws_autoscaling_group" "app" {
name = "certlabpro-saa-c03-app-asg"
vpc_zone_identifier = aws_subnet.private[*].id
target_group_arns = [aws_lb_target_group.web.arn]
health_check_type = "ELB"
min_size = 2
max_size = 4
desired_capacity = 2
launch_template {
id = aws_launch_template.app.id
version = "$Latest"
}
}Le joyau de toute architecture multi-AZ SAA-C03 est une base de données RDS Multi-AZ. Le paramètre multi_az = true est l'un des attributs les plus testés de tout l'examen : il indique à RDS de provisionner une réplique en veille synchrone dans une seconde AZ. Lorsque la base de données principale échoue, RDS promeut automatiquement la réplique en veille — un basculement typique prend environ 60 secondes sans perte de données. Deux bases de données Single-AZ ne vous donneraient PAS cela ; la réplication manuelle ne vous donnerait PAS cela. Le Multi-AZ est la réponse à toute question de "basculement en moins d'une minute, zéro perte de données".
Le groupe de sous-réseaux de base de données a besoin de sous-réseaux dans au moins deux AZ — nous lui fournissons les sous-réseaux privés de l'Étape 2. Le groupe de sécurité accepte le port de la base de données (5432 pour PostgreSQL) uniquement depuis le groupe de sécurité de l'application, reproduisant le modèle de sécurité en couches de l'Étape 4.
Avec cette dernière pièce en place, la pile est complète : le trafic entre l'ALB dans l'une ou l'autre AZ publique, est réparti vers les instances ASG dans l'une ou l'autre AZ privée, et ces instances communiquent avec la base de données RDS principale (qui a une réplique en veille chaude dans l'autre AZ). Tout, sauf une panne totale de région, dispose d'un chemin de récupération.
resource "aws_db_subnet_group" "main" {
name = "certlabpro-saa-c03"
subnet_ids = aws_subnet.private[*].id
}
resource "aws_security_group" "db" {
name = "certlabpro-saa-c03-db"
description = "DB accepts traffic only from the app SG"
vpc_id = aws_vpc.main.id
ingress {
from_port = 5432
to_port = 5432
protocol = "tcp"
security_groups = [aws_security_group.app.id]
}
}
resource "aws_db_instance" "main" {
identifier = "certlabpro-saa-c03"
engine = "postgres"
engine_version = "16"
instance_class = "db.t3.micro"
allocated_storage = 20
storage_encrypted = true
multi_az = true # the SAA-C03 headline
db_subnet_group_name = aws_db_subnet_group.main.name
vpc_security_group_ids = [aws_security_group.db.id]
username = "appuser"
password = "ChangeMe-Not-For-Prod-1234" # use Secrets Manager in production
skip_final_snapshot = true # lab-only setting; never use on prod
apply_immediately = true
}terraform destroy déconstruit tout dans ce lab. Deux remarques :
skip_final_snapshot = true, donc destroy se termine en quelques minutes sans laisser de snapshot derrière. N'activez jamais cet indicateur sur une base de données de production — perdre le snapshot final est une perte de données permanente.destroy pour l'ASG lui-même ne se termine pas tant que toutes les instances ne sont pas parties, ce qui peut prendre 2 à 3 minutes. Soyez patient.Ctrl-C au milieu de la destruction — laissez-la se terminer.Le SAA-C03 couvre plus de modèles architecturaux qu'un seul lab ne peut en démontrer — CloudFront pour la distribution globale de contenu, Route 53 pour le basculement basé sur DNS, la réplication inter-régions S3, Aurora Global Database, Direct Connect, le peering VPC, Transit Gateway, ElastiCache, EFS, FSx, et bien d'autres encore.
Nous nous en tenons délibérément au modèle le plus testé de l'examen : la haute disponibilité multi-AZ au sein d'une seule région. C'est l'architecture qui revient dans chaque entretien d'architecte de solutions et environ 30% des questions du SAA-C03. Les 70% restants — modèles globaux, mise en cache, mise en réseau avancée, cloud hybride — sont traités conceptuellement dans les sections Parcourir et Editorial de cette page de certification. Chaque sujet inter-régions ou de mise en réseau avancée mérite son propre lab ; construire une méga-pile diluerait la discipline narrative de construction sur laquelle ce format repose.
Si vous souhaitez une pratique concrète des modèles inter-régions (S3 CRR, Aurora Global, vérifications de santé Route 53), ceux-ci se prêtent facilement à la même forme Terraform simple et sont de bons candidats pour des labs de suivi.