Dernière révision : mai 2026
Configurez les services AWS figurant à l'examen ANS-C01 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 laboratoire, vous aurez provisionné, avec du Terraform simple, le backbone AWS multi-VPC canonique — deux VPC à double pile (IPv4 + IPv6) dans la même région, connectés via une Transit Gateway avec des associations de tables de routage explicites, et des journaux de flux VPC (VPC Flow Logs) sauvegardés par CloudWatch sur le VPC principal afin que vous puissiez réellement voir ce qui traverse votre réseau. C'est l'architecture que suppose chaque question ANS-C01 concernant les multi-VPC.
Chaque ressource est du Terraform simple. Déposez les extraits dans un unique fichier main.tf, exécutez terraform init, puis terraform apply étape par étape.
>= 1.5 ou OpenTofu >= 1.6.us-east-1.La majeure partie de ce laboratoire est peu coûteuse ou gratuite, mais la Transit Gateway n'est pas :
Les frais horaires de la TGW sont le coût principal de ce laboratoire. Deux attachements × 0,05 $/heure × 24 heures × 30 jours ≈ 72 $/mois tant qu'elle est en cours d'exécution. Détruisez-la dès que vous avez terminé votre exploration — la TGW est le plus grand piège de coût dans tout laboratoire ANS-C01.
Introduction standard. La Transit Gateway est régionale — tous les attachements doivent se trouver dans la région où réside la TGW. Pour la connectivité inter-régions, vous ajouteriez le peering TGW (hors de portée pour la v1). Nous utilisons us-east-1 par défaut.
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-ans-c01"
ManagedBy = "terraform"
}
}
}
data "aws_availability_zones" "available" {
state = "available"
}ANS-C01 teste spécifiquement les VPC à double pile — AWS attribue désormais par défaut un /56 IPv6 à chaque nouveau VPC si vous définissez assign_generated_ipv6_cidr_block = true. Le domaine Conception de réseau de l'examen teste à la fois le calcul de planification CIDR IPv4 (des /16 non-superposés si vous voulez faire du peering ou un attachement TGW) et la dérivation de sous-réseau IPv6 (chaque sous-réseau obtient un /64 découpé du /56 du VPC).
Nous assignons 10.0.0.0/16 pour IPv4 et un /56 IPv6 généré automatiquement par AWS. Le sous-réseau unique ici utilise un bloc IPv4 en /24 et un bloc IPv6 en /64 découpé du /56 du VPC — cidrsubnet est la fonction Terraform intégrée pour ce calcul. La passerelle Internet est à double pile par défaut dans les régions AWS modernes.
resource "aws_vpc" "primary" {
cidr_block = "10.0.0.0/16"
assign_generated_ipv6_cidr_block = true
enable_dns_hostnames = true
tags = { Name = "certlabpro-ans-c01-primary" }
}
resource "aws_subnet" "primary_a" {
vpc_id = aws_vpc.primary.id
cidr_block = "10.0.1.0/24"
ipv6_cidr_block = cidrsubnet(aws_vpc.primary.ipv6_cidr_block, 8, 1)
availability_zone = data.aws_availability_zones.available.names[0]
assign_ipv6_address_on_creation = true
tags = { Name = "certlabpro-ans-c01-primary-a" }
}
resource "aws_internet_gateway" "primary" {
vpc_id = aws_vpc.primary.id
}Nous construisons un second VPC à 10.1.0.0/16 — délibérément non-superposé au 10.0.0.0/16 du VPC #1. L'ANS-C01 insiste sur cette règle de conception car dès que vous voulez connecter deux VPC (peering, TGW, quoi que ce soit), les CIDR superposés l'interdisent au niveau de l'API AWS. Vous ne pouvez pas acheminer vers un CIDR qui est également revendiqué localement.
Le VPC #2 obtient également son propre /56 IPv6 généré automatiquement par AWS (chaque VPC reçoit un bloc globalement unique, il n'y a donc pas de risque de chevauchement IPv6 par défaut). Le calcul de découpage du sous-réseau est de la même forme qu'à l'étape 2.
resource "aws_vpc" "secondary" {
cidr_block = "10.1.0.0/16"
assign_generated_ipv6_cidr_block = true
enable_dns_hostnames = true
tags = { Name = "certlabpro-ans-c01-secondary" }
}
resource "aws_subnet" "secondary_a" {
vpc_id = aws_vpc.secondary.id
cidr_block = "10.1.1.0/24"
ipv6_cidr_block = cidrsubnet(aws_vpc.secondary.ipv6_cidr_block, 8, 1)
availability_zone = data.aws_availability_zones.available.names[0]
assign_ipv6_address_on_creation = true
tags = { Name = "certlabpro-ans-c01-secondary-a" }
}La Transit Gateway est le hub. Elle peut gérer des milliers d'attachements de VPC, prend en charge le partage inter-comptes via AWS Resource Access Manager (RAM), et vous offre une seule table de routage à considérer au lieu de N² connexions de peering. L'ANS-C01 teste ce choix d'architecture en étoile (hub-and-spoke) plutôt que le peering de VPC chaque fois que la question mentionne «plus de trois VPC» ou «à mesure que notre réseau se développe».
Nous créons la TGW avec l'association et la propagation de table de routage par défaut désactivées — c'est le modèle ANS-C01 le plus souvent testé car il vous oblige à être explicite sur les attachements qui peuplent quelles tables de routage. L'auto-association est le réglage de commodité; le manuel est le réglage favorable à l'audit.
La ressource d'attachement est le pont par VPC. Avec les deux VPC attachés, la TGW connaît leurs deux CIDR; nous devons toujours ajouter des routes depuis la table de routage principale de chaque VPC pointant vers la TGW (Étape 5).
resource "aws_ec2_transit_gateway" "hub" {
description = "certlabpro-ans-c01 hub"
default_route_table_association = "disable"
default_route_table_propagation = "disable"
multicast_support = "disable"
tags = { Name = "certlabpro-ans-c01-tgw" }
}
resource "aws_ec2_transit_gateway_route_table" "main" {
transit_gateway_id = aws_ec2_transit_gateway.hub.id
tags = { Name = "certlabpro-ans-c01-tgw-rt" }
}
resource "aws_ec2_transit_gateway_vpc_attachment" "primary" {
transit_gateway_id = aws_ec2_transit_gateway.hub.id
vpc_id = aws_vpc.primary.id
subnet_ids = [aws_subnet.primary_a.id]
transit_gateway_default_route_table_association = false
transit_gateway_default_route_table_propagation = false
}
resource "aws_ec2_transit_gateway_vpc_attachment" "secondary" {
transit_gateway_id = aws_ec2_transit_gateway.hub.id
vpc_id = aws_vpc.secondary.id
subnet_ids = [aws_subnet.secondary_a.id]
transit_gateway_default_route_table_association = false
transit_gateway_default_route_table_propagation = false
}
resource "aws_ec2_transit_gateway_route_table_association" "primary" {
transit_gateway_attachment_id = aws_ec2_transit_gateway_vpc_attachment.primary.id
transit_gateway_route_table_id = aws_ec2_transit_gateway_route_table.main.id
}
resource "aws_ec2_transit_gateway_route_table_association" "secondary" {
transit_gateway_attachment_id = aws_ec2_transit_gateway_vpc_attachment.secondary.id
transit_gateway_route_table_id = aws_ec2_transit_gateway_route_table.main.id
}
resource "aws_ec2_transit_gateway_route_table_propagation" "primary" {
transit_gateway_attachment_id = aws_ec2_transit_gateway_vpc_attachment.primary.id
transit_gateway_route_table_id = aws_ec2_transit_gateway_route_table.main.id
}
resource "aws_ec2_transit_gateway_route_table_propagation" "secondary" {
transit_gateway_attachment_id = aws_ec2_transit_gateway_vpc_attachment.secondary.id
transit_gateway_route_table_id = aws_ec2_transit_gateway_route_table.main.id
}La TGW de l'étape 4 connaît les deux VPC, mais la table de routage de chaque VPC ne sait toujours pas comment atteindre l'autre. Nous ajoutons des routes explicites dans les deux sens : la table de routage du VPC #1 envoie le trafic 10.1.0.0/16 à la TGW, et vice versa. L'examen teste à plusieurs reprises cette exigence bidirectionnelle — «J'ai attaché les deux à la TGW, pourquoi ne peuvent-ils pas se pinguer ?» est presque toujours dû à une route de retour manquante.
Enfin, les journaux de flux VPC (VPC Flow Logs). Le domaine Surveillance réseau de l'ANS-C01 les teste comme le seul moyen de voir quels paquets traversent réellement votre réseau — acceptés, rejetés, et uniquement les métadonnées (5-tuple + octets + paquets + résultat). Nous les activons pour le VPC principal, avec des journaux qui sont envoyés vers un groupe de journaux CloudWatch dédié. Le rôle IAM que nous attachons est celui que les Flow Logs assument pour écrire dans le groupe de journaux.
Avec les routes en place et les Flow Logs en cours d'exécution, le backbone est complet. Deux VPC à double pile, connectés via une TGW avec un routage explicite (favorable à l'audit), avec une visibilité au niveau des paquets du côté principal. Chaque modèle ANS-C01 additionnel (Direct Connect Gateway, peering TGW, NAT, PrivateLink, points d'accès VPC) s'attache à cette base.
resource "aws_route" "primary_to_secondary" {
route_table_id = aws_vpc.primary.main_route_table_id
destination_cidr_block = "10.1.0.0/16"
transit_gateway_id = aws_ec2_transit_gateway.hub.id
depends_on = [aws_ec2_transit_gateway_vpc_attachment.primary]
}
resource "aws_route" "secondary_to_primary" {
route_table_id = aws_vpc.secondary.main_route_table_id
destination_cidr_block = "10.0.0.0/16"
transit_gateway_id = aws_ec2_transit_gateway.hub.id
depends_on = [aws_ec2_transit_gateway_vpc_attachment.secondary]
}
# ── VPC Flow Logs ─────────────────────────────────────────────
resource "aws_cloudwatch_log_group" "vpc_flow" {
name = "/aws/vpc-flow/certlabpro-ans-c01-primary"
retention_in_days = 30
}
resource "aws_iam_role" "vpc_flow" {
name = "certlabpro-ans-c01-vpc-flow"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Effect = "Allow"
Principal = { Service = "vpc-flow-logs.amazonaws.com" }
Action = "sts:AssumeRole"
}]
})
}
resource "aws_iam_role_policy" "vpc_flow" {
name = "write-flow-logs"
role = aws_iam_role.vpc_flow.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Effect = "Allow"
Action = [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents",
"logs:DescribeLogGroups",
"logs:DescribeLogStreams",
]
Resource = aws_cloudwatch_log_group.vpc_flow.arn
}]
})
}
resource "aws_flow_log" "primary" {
vpc_id = aws_vpc.primary.id
traffic_type = "ALL"
log_destination_type = "cloud-watch-logs"
log_destination = aws_cloudwatch_log_group.vpc_flow.arn
iam_role_arn = aws_iam_role.vpc_flow.arn
max_aggregation_interval = 60
}terraform destroy supprime tout dans ce laboratoire, mais soyez prudent avec l'ordre — les attachements de Transit Gateway prennent 5 à 10 minutes à se détacher, et la TGW elle-même ne peut être supprimée tant que les deux attachements ne sont pas complètement partis. terraform destroy gère correctement le graphe de dépendances, mais l'opération n'est pas rapide. Ne faites pas Ctrl-C au milieu de la destruction ou vous vous retrouverez avec des attachements à moitié détachés que vous devrez nettoyer via la console.
La principale raison de détruire rapidement est le coût horaire de la TGW — deux attachements à 0,05 $/heure chacun = 72 $/mois combinés. Le coût du laboratoire s'accumule rapidement si vous oubliez qu'il est en cours d'exécution.
L'ANS-C01 couvre des aspects réseau que ce laboratoire ne peut pas aborder — Direct Connect (pas d'environnement de test sans port physique), AWS Site-to-Site VPN (nécessite un point d'accès côté client), les points d'accès entrants/sortants de Route 53 Resolver pour le DNS hybride, les services PrivateLink + points d'accès VPC, AWS Network Firewall, AWS Global Accelerator, les vérifications de santé + basculement de Route 53, Network Access Analyzer, Reachability Analyzer, peering de Transit Gateway (inter-régions), Cloud WAN, AWS App Mesh, et les scénarios spécifiques au BGP (filtrage de routes, prépend, manipulation de AS-PATH).
Nous nous en tenons à la forme de backbone multi-VPC car c'est l'architecture la plus testée à l'examen — les attachements Direct Connect, les tunnels VPN, le DNS hybride et PrivateLink s'ancrent tous à ce type de hub TGW. Maîtrisez l'architecture en étoile (hub-and-spoke) ; les types de branches en sont des extensions.
Pour les surfaces non provisionnées, les sections Parcourir, Guide et Editorial de cette page de certification offrent une couverture conceptuelle. Un laboratoire de suivi ajoutant Route 53 Resolver + un attachement VPN + PrivateLink compléterait l'histoire du réseau hybride.