AWS - Intermédiaire : VPC, RDS, Lambda et CloudFormation
🎯 Objectifs
- ✅ Concevoir un réseau VPC avec sous-réseaux publics et privés
- ✅ Déployer une base de données RDS managée
- ✅ Créer des fonctions Lambda déclenchées par des événements
- ✅ Automatiser le déploiement d'infrastructure avec CloudFormation
- ✅ Configurer un Elastic Load Balancer et un Auto Scaling Group
📋 Prérequis
- AWS Débutant (IAM, EC2, S3, AWS CLI configurée)
- Connaissances réseau de base (IP, sous-réseaux, CIDR)
🌐 VPC - Virtual Private Cloud
Pourquoi un VPC ?
Par défaut, AWS vous donne un VPC par région. Mais en production, vous créez vos propres VPC pour isoler vos environnements (dev, staging, prod) et contrôler précisément les flux réseau.
💡 Analogie : le VPC est comme le plan d'un immeuble que vous dessinez. Vous décidez des étages (sous-réseaux), des portes (security groups), et de qui peut entrer par l'entrée principale (internet gateway).
Architecture typique
VPC : 10.0.0.0/16
├── Sous-réseau public 10.0.1.0/24 (az-a) ← Accessible depuis Internet
│ └── Bastion, Load Balancer
├── Sous-réseau public 10.0.2.0/24 (az-b)
│ └── Bastion, Load Balancer
├── Sous-réseau privé 10.0.10.0/24 (az-a) ← Pas d'accès Internet direct
│ └── EC2, ECS, Lambda
└── Sous-réseau privé 10.0.20.0/24 (az-b)
└── EC2, ECS, LambdaComposants clés du VPC
| Composant | Rôle |
|---|---|
| Internet Gateway (IGW) | Porte d'entrée vers Internet pour les sous-réseaux publics |
| NAT Gateway | Permet aux ressources privées d'accéder à Internet (sens sortant seulement) |
| Route Table | Décide où va le trafic selon la destination |
| Security Group | Pare-feu au niveau instance (stateful) |
| NACL | Pare-feu au niveau sous-réseau (stateless) |
Créer un VPC complet
# 1. Créer le VPC
VPC_ID=$(aws ec2 create-vpc \
--cidr-block 10.0.0.0/16 \
--query 'Vpc.VpcId' --output text)
aws ec2 create-tags --resources $VPC_ID --tags Key=Name,Value=mon-vpc
# 2. Créer les sous-réseaux
SUBNET_PUB=$(aws ec2 create-subnet \
--vpc-id $VPC_ID \
--cidr-block 10.0.1.0/24 \
--availability-zone eu-west-3a \
--query 'Subnet.SubnetId' --output text)
SUBNET_PRIV=$(aws ec2 create-subnet \
--vpc-id $VPC_ID \
--cidr-block 10.0.10.0/24 \
--availability-zone eu-west-3a \
--query 'Subnet.SubnetId' --output text)
# 3. Créer et attacher l'Internet Gateway
IGW_ID=$(aws ec2 create-internet-gateway --query 'InternetGateway.InternetGatewayId' --output text)
aws ec2 attach-internet-gateway --internet-gateway-id $IGW_ID --vpc-id $VPC_ID
# 4. Configurer la route table publique
RTB_ID=$(aws ec2 create-route-table --vpc-id $VPC_ID --query 'RouteTable.RouteTableId' --output text)
aws ec2 create-route --route-table-id $RTB_ID --destination-cidr-block 0.0.0.0/0 --gateway-id $IGW_ID
aws ec2 associate-route-table --route-table-id $RTB_ID --subnet-id $SUBNET_PUBSecurity Groups vs NACLs
| Critère | Security Group | NACL |
|---|---|---|
| Niveau | Instance | Sous-réseau |
| État | Stateful (réponses autorisées auto) | Stateless (règles entrée ET sortie) |
| Règles | Allow uniquement | Allow et Deny |
| Ordre des règles | Toutes évaluées | Ordre numérique (priorité) |
🗄️ RDS - Relational Database Service
Pourquoi RDS au lieu d'installer MySQL soi-même ?
Gérer une base de données en production est complexe : sauvegardes, mises à jour, réplication, failover... RDS automatise tout cela.
| Géré par RDS | Géré par vous si self-hosted |
|---|---|
| Sauvegardes automatiques | Configurer cron + mysqldump |
| Mises à jour de sécurité | Appliquer les patches manuellement |
| Réplication Multi-AZ | Configurer la réplication |
| Monitoring intégré | Installer des agents |
Moteurs disponibles
- Amazon Aurora : compatible MySQL/PostgreSQL, 5× plus rapide, AWS-optimisé
- MySQL : 5.7, 8.0
- PostgreSQL : 13, 14, 15, 16
- MariaDB, Oracle, SQL Server
Créer une instance RDS
# Créer un subnet group (obligatoire pour RDS)
aws rds create-db-subnet-group \
--db-subnet-group-name mon-subnet-group \
--db-subnet-group-description "Subnet group pour RDS" \
--subnet-ids subnet-xxxx subnet-yyyy
# Lancer une instance RDS PostgreSQL
aws rds create-db-instance \
--db-instance-identifier ma-base \
--db-instance-class db.t3.micro \
--engine postgres \
--engine-version 15.4 \
--master-username admin \
--master-user-password MonMotDePasse123! \
--allocated-storage 20 \
--db-subnet-group-name mon-subnet-group \
--vpc-security-group-ids sg-xxxx \
--multi-az \
--backup-retention-period 7 \
--no-publicly-accessible
# Suivre la création (prend ~5 minutes)
aws rds describe-db-instances \
--db-instance-identifier ma-base \
--query 'DBInstances[0].DBInstanceStatus'Multi-AZ et Read Replicas
Multi-AZ : RDS maintient une copie synchrone dans une autre AZ. En cas de panne, le basculement est automatique (30-60 secondes). Recommandé pour la production.
Read Replicas : copies asynchrones pour décharger les requêtes de lecture. Jusqu'à 5 réplicas par instance. Peuvent être promus en instance principale.
⚡ Lambda - Functions as a Service
Concept
Lambda exécute du code sans que vous gériez de serveur. Vous payez uniquement les millisecondes d'exécution. C'est le coeur du serverless sur AWS.
💡 Analogie : une fonction Lambda, c'est comme un micro-ondes. Vous posez quelque chose dedans (l'événement), appuyez sur le bouton (le déclencheur), et récupérez le résultat. Vous ne gérez pas le moteur de chauffage.
Runtimes disponibles
Node.js 20, Python 3.12, Java 21, Go 1.x, Ruby 3.2, .NET 8, et runtime personnalisé.
Déclencheurs courants
| Déclencheur | Cas d'usage |
|---|---|
| API Gateway | API REST/HTTP |
| S3 | Traiter un fichier à l'upload |
| SQS | Consommer des messages d'une file |
| EventBridge | Tâches planifiées (cron) |
| DynamoDB Streams | Réagir aux changements en base |
| SNS | Réagir aux notifications |
Créer une fonction Lambda
# Créer le code de la fonction (fichier lambda_function.py)
cat > lambda_function.py << 'EOF'
import json
def lambda_handler(event, context):
"""
Fonction Lambda simple : retourne un message avec les données reçues.
event : dict contenant les données de l'événement déclencheur
context : informations sur l'exécution (timeout restant, etc.)
"""
name = event.get('name', 'Monde')
return {
'statusCode': 200,
'body': json.dumps({'message': f'Bonjour {name} depuis Lambda!'})
}
EOF
# Zipper le code
zip function.zip lambda_function.py
# Créer la fonction
aws lambda create-function \
--function-name ma-fonction \
--runtime python3.12 \
--role arn:aws:iam::ACCOUNT_ID:role/lambda-role \
--handler lambda_function.lambda_handler \
--zip-file fileb://function.zip \
--timeout 30 \
--memory-size 128
# Invoquer la fonction
aws lambda invoke \
--function-name ma-fonction \
--payload '{"name": "Alice"}' \
--cli-binary-format raw-in-base64-out \
output.json
cat output.json
# {"statusCode": 200, "body": "{\"message\": \"Bonjour Alice depuis Lambda!\"}"}Cold Start
Quand une fonction Lambda est invoquée pour la première fois (ou après une période d'inactivité), AWS doit démarrer un conteneur - c'est le cold start (latence supplémentaire de 100ms à quelques secondes selon le runtime et la taille du déploiement).
Solutions : provisioned concurrency, optimiser la taille du package, éviter les runtimes JVM pour les fonctions latence-sensibles.
🏗️ CloudFormation - Infrastructure as Code
Pourquoi CloudFormation ?
Créer des ressources à la main depuis la console est risqué : étapes oubliées, différences entre environnements, impossible à reproduire. CloudFormation décrit toute l'infrastructure dans un fichier YAML versionnable.
💡 Analogie : CloudFormation, c'est comme une recette de cuisine. La recette décrit les ingrédients (ressources) et les étapes. Si vous suivez la recette deux fois, vous obtenez le même plat.
Structure d'un template
AWSTemplateFormatVersion: '2010-09-09'
Description: "Stack exemple : EC2 + Security Group"
# Variables d'entrée
Parameters:
InstanceType:
Type: String
Default: t3.micro
AllowedValues: [t3.micro, t3.small, t3.medium]
Description: "Type d'instance EC2"
KeyPairName:
Type: AWS::EC2::KeyPair::KeyName
Description: "Paire de clés SSH"
# Ressources à créer
Resources:
WebServerSG:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: "Security Group serveur web"
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort: 443
ToPort: 443
CidrIp: 0.0.0.0/0
WebServer:
Type: AWS::EC2::Instance
Properties:
InstanceType: !Ref InstanceType # Référence au paramètre
KeyName: !Ref KeyPairName
ImageId: ami-0c02fb55956c7d316
SecurityGroupIds:
- !Ref WebServerSG # Référence à la ressource ci-dessus
UserData:
Fn::Base64: |
#!/bin/bash
yum update -y
yum install -y httpd
systemctl start httpd
systemctl enable httpd
# Valeurs exportées
Outputs:
PublicIP:
Description: "Adresse IP publique du serveur"
Value: !GetAtt WebServer.PublicIp # Attribut de la ressource
Export:
Name: WebServerPublicIPCommandes CloudFormation
# Valider le template avant déploiement
aws cloudformation validate-template --template-body file://stack.yaml
# Créer la stack
aws cloudformation create-stack \
--stack-name mon-stack \
--template-body file://stack.yaml \
--parameters \
ParameterKey=InstanceType,ParameterValue=t3.micro \
ParameterKey=KeyPairName,ParameterValue=ma-cle \
--capabilities CAPABILITY_IAM
# Suivre la création
aws cloudformation describe-stacks \
--stack-name mon-stack \
--query 'Stacks[0].StackStatus'
# Mettre à jour une stack
aws cloudformation update-stack \
--stack-name mon-stack \
--template-body file://stack.yaml
# Créer un change set (voir les changements avant d'appliquer)
aws cloudformation create-change-set \
--stack-name mon-stack \
--change-set-name mes-modifications \
--template-body file://stack-v2.yaml
# Supprimer la stack (et toutes ses ressources)
aws cloudformation delete-stack --stack-name mon-stack⚖️ Elastic Load Balancer et Auto Scaling
Application Load Balancer (ALB)
L'ALB distribue le trafic HTTP/HTTPS entre plusieurs instances EC2. Il opère au niveau 7 (application) et peut router selon l'URL, les headers ou le host.
Internet → ALB → Target Group → EC2 instances
├── i-aaa (zone a)
├── i-bbb (zone b)
└── i-ccc (zone a)Auto Scaling Group
Un ASG maintient automatiquement un nombre d'instances défini et s'adapte à la charge.
# Créer un Launch Template (modèle de configuration d'instance)
aws ec2 create-launch-template \
--launch-template-name mon-template \
--launch-template-data '{
"ImageId": "ami-0c02fb55956c7d316",
"InstanceType": "t3.micro",
"KeyName": "ma-cle",
"SecurityGroupIds": ["sg-xxxx"]
}'
# Créer l'Auto Scaling Group
aws autoscaling create-auto-scaling-group \
--auto-scaling-group-name mon-asg \
--launch-template LaunchTemplateName=mon-template,Version='$Latest' \
--min-size 2 \
--max-size 6 \
--desired-capacity 2 \
--availability-zones eu-west-3a eu-west-3b \
--target-group-arns arn:aws:elasticloadbalancing:...
# Créer une politique de scaling (ex: ajouter une instance si CPU > 70%)
aws autoscaling put-scaling-policy \
--auto-scaling-group-name mon-asg \
--policy-name cpu-scale-up \
--policy-type TargetTrackingScaling \
--target-tracking-configuration '{
"PredefinedMetricSpecification": {"PredefinedMetricType": "ASGAverageCPUUtilization"},
"TargetValue": 70.0
}'📌 Points Clés
- Un VPC structure votre réseau : sous-réseaux publics (internet) et privés (isolés)
- RDS gère les sauvegardes, mises à jour et réplication - utilisez Multi-AZ en production
- Lambda exécute du code sans serveur ; vous payez à la milliseconde
- CloudFormation versionne votre infrastructure comme du code - reproductible et auditables
- ALB + ASG = haute disponibilité et élasticité automatique
📚 Ressources
- Documentation VPC
- Documentation RDS
- Documentation Lambda
- Documentation CloudFormation
- Référence des types de ressources CloudFormation
🚀 Prochaines étapes
Vous maîtrisez les services clés d'AWS. Passez au niveau avancé :
- AWS Avancé : ECS, IAM avancé et architecture multi-région - conteneurs, sécurité poussée et haute disponibilité globale