Introduction
AWS CloudFormation révolutionne l'Infrastructure as Code (IaC) en modelant vos ressources cloud sous forme de templates déclaratives. En 2026, avec l'essor des environnements multi-cloud hybrides, maîtriser CloudFormation est essentiel pour les DevOps : il garantit la reproductibilité, la versionning et l'audit des déploiements. Ce tutoriel intermédiaire vous guide pas à pas pour créer une stack complète incluant VPC, sous-réseaux, instance EC2 sécurisée et bucket S3. Vous apprendrez à utiliser des paramètres dynamiques, des outputs pour inter-opérabilité, et des commandes CLI avancées. À la fin, vous déployez une infra scalable en 10 minutes, évitant les pièges classiques comme les dépendances circulaires. Idéal pour scaler vos apps sans downtime. (128 mots)
Prérequis
- Compte AWS actif avec permissions IAM :
cloudformation:,ec2:,s3:,vpc:(attachez la policyAdministratorAccesspour tests). - AWS CLI v2 installée et configurée (
aws configureavec access key). - Région AWS par défaut :
us-east-1(modifiable via--region). - Connaissances de base en YAML et networking AWS.
- Outil
cfn-lintpour validation :pip install cfn-lint.
Template S3 bucket basique
AWSTemplateFormatVersion: '2010-09-09'
Description: 'Bucket S3 avec versioning et chiffrement'
Resources:
MyS3Bucket:
Type: AWS::S3::Bucket
Properties:
BucketName: !Sub 'mon-bucket-${AWS::AccountId}-${AWS::Region}'
VersioningConfiguration:
Status: Enabled
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: AES256
Outputs:
BucketName:
Description: Nom du bucket créé
Value: !Ref MyS3Bucket
Export:
Name: !Sub '${AWS::StackName}-BucketName'Ce template crée un bucket S3 unique (via !Sub avec AccountId et Region) avec versioning pour audits et chiffrement AES256 par défaut. L'output exporté permet de référencer ce bucket dans d'autres stacks. Piège à éviter : noms de buckets globaux, d'où l'unicité forcée ; testez avec aws s3 ls post-déploiement.
Bases des templates CloudFormation
Chaque template commence par AWSTemplateFormatVersion pour la compatibilité (2010-09-09 est stable). La section Resources déclare les primitives AWS (S3::Bucket ici). Utilisez des intrinsic functions comme !Ref (référence resource), !Sub (substitution) et !GetAtt (attributs). Outputs exposent des valeurs pour cross-stack references. Validez toujours avec cfn-lint s3-bucket.yaml avant déploiement pour catcher les syntaxes YAML ou logiques.
Template VPC et sous-réseaux
AWSTemplateFormatVersion: '2010-09-09'
Description: 'VPC avec public/private subnets'
Parameters:
VpcCidr:
Type: String
Default: 10.0.0.0/16
Description: CIDR du VPC
Resources:
MyVPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: !Ref VpcCidr
EnableDnsHostnames: true
EnableDnsSupport: true
Tags:
- Key: Name
Value: !Sub '${AWS::StackName}-VPC'
PublicSubnet:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref MyVPC
CidrBlock: 10.0.1.0/24
AvailabilityZone: !Select [0, !GetAZs '']
MapPublicIpOnLaunch: true
Tags:
- Key: Name
Value: !Sub '${AWS::StackName}-Public'
InternetGateway:
Type: AWS::EC2::InternetGateway
AttachGateway:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId: !Ref MyVPC
InternetGatewayId: !Ref InternetGateway
PublicRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref MyVPC
PublicRoute:
Type: AWS::EC2::Route
DependsOn: AttachGateway
Properties:
RouteTableId: !Ref PublicRouteTable
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref InternetGateway
PublicSubnetRouteTableAssoc:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PublicSubnet
RouteTableId: !Ref PublicRouteTable
Outputs:
VpcId:
Value: !Ref MyVPC
Export:
Name: !Sub '${AWS::StackName}-VpcId'
PublicSubnetId:
Value: !Ref PublicSubnet
Export:
Name: !Sub '${AWS::StackName}-PublicSubnetId'Ce template déploie une VPC /16 avec un subnet public routé vers un IGW pour accès internet. Le paramètre VpcCidr permet la customisation ; DependsOn gère les dépendances. Outputs exportés facilitent l'intégration EC2. Attention au piège des AZ : !GetAZs '' liste les AZ disponibles ; déployez en us-east-1 pour fiabilité.
Gestion des réseaux et dépendances
DependsOn ordonne la création (IGW avant route). Utilisez Tags pour filtrer en console. Pour private subnets, ajoutez NAT Gateway (coût ~30$/mois). Testez connectivité : aws ec2 describe-route-tables --route-table-ids $(aws cloudformation describe-stacks --stack-name test-vpc --query 'Stacks[0].Outputs[?OutputKey==PublicSubnetId].OutputValue' --output text).
Instance EC2 sécurisée dans VPC
AWSTemplateFormatVersion: '2010-09-09'
Description: 'EC2 Ubuntu dans VPC avec SG'
Parameters:
VpcId:
Type: AWS::EC2::VPC::Id
PublicSubnetId:
Type: AWS::EC2::Subnet::Id
KeyName:
Type: AWS::EC2::KeyPair::KeyName
Description: Nom de la clé SSH (créez-en une avant)
Resources:
WebSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Accès SSH/HTTP
VpcId: !Ref VpcId
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
WebServer:
Type: AWS::EC2::Instance
Properties:
InstanceType: t3.micro
ImageId: ami-0c02fb55956c7d316 # Ubuntu 22.04 us-east-1, vérifiez ami actuelle
KeyName: !Ref KeyName
SubnetId: !Ref PublicSubnetId
SecurityGroupIds:
- !Ref WebSecurityGroup
UserData:
Fn::Base64: !Sub |
#!/bin/bash
apt-get update -y
apt-get install -y apache2
systemctl start apache2
echo "<h1>CloudFormation OK!</h1>" > /var/www/html/index.html
Outputs:
InstancePublicIp:
Description: IP publique de l'EC2
Value: !GetAtt WebServer.PublicIpIntègre VPC via paramètres ; SG autorise SSH/HTTP mondial (restreignez en prod). UserData bootstrappe Apache automatiquement. AMI Ubuntu spécifique à us-east-1 (trouvez via AWS console). Piège : sans KeyName, pas d'accès SSH ; ssh -i key.pem ubuntu@IP pour tester. Output IP pour monitoring.
Intégration EC2 et UserData
UserData s'exécute au boot (base64 encodé). Fn::Base64 et !Sub interpolent. Pour AMI dynamique : AWS::SSM::Parameter::Value avec /aws/service/ami-amazon-linux-latest. Scalez avec AutoScalingGroup pour prod.
Template complet avec S3 et outputs
AWSTemplateFormatVersion: '2010-09-09'
Description: 'Stack complète VPC+EC2+S3'
Parameters:
KeyName:
Type: AWS::EC2::KeyPair::KeyName
Resources:
# Intégrez VPC/EC2/S3 ici (combinaison des précédents)
MyS3Bucket:
Type: AWS::S3::Bucket
Properties:
BucketName: !Sub 'fullstack-${AWS::AccountId}'
# ... (ajoutez VPC, EC2 comme ci-dessus)
Outputs:
WebsiteURL:
Value: !Sub 'http://${WebServer.PublicIp}'
BucketURL:
Value: !Sub 'https://${MyS3Bucket}.s3.amazonaws.com'Template consolidé réutilisant outputs cross-stack (importez VpcId via Fn::ImportValue). Ajoutez toutes resources. Pour full : copiez VPC+EC2+S3. Outputs composés pour CI/CD. Piège : circular refs évitées par DependsOn explicite.
Script déploiement CLI
#!/bin/bash
STACK_NAME="demo-stack"
TEMPLATE="full-stack.yaml"
# Créer ou updater stack
if aws cloudformation describe-stacks --stack-name $STACK_NAME &>/dev/null; then
echo "Update en cours..."
aws cloudformation update-stack \
--stack-name $STACK_NAME \
--template-body file://$TEMPLATE \
--capabilities CAPABILITY_IAM \
--parameters ParameterKey=KeyName,ParameterValue=votre-key
else
echo "Création stack..."
aws cloudformation create-stack \
--stack-name $STACK_NAME \
--template-body file://$TEMPLATE \
--capabilities CAPABILITY_IAM \
--parameters ParameterKey=KeyName,ParameterValue=votre-key
fi
# Attendre completion
aws cloudformation wait stack-create-complete --stack-name $STACK_NAME || aws cloudformation wait stack-update-complete --stack-name $STACK_NAME
echo "Outputs:"
aws cloudformation describe-stacks --stack-name $STACK_NAME --query 'Stacks[0].Outputs'Script idempotent : create/update auto. --capabilities CAPABILITY_IAM pour roles auto-créés. wait évite race conditions. Remplacez votre-key. Exécutez chmod +x deploy.sh && ./deploy.sh. Pour delete : aws cloudformation delete-stack --stack-name demo-stack.
Bonnes pratiques
- Modularisez : Stacks nested (AWS::CloudFormation::Stack) pour réutilisabilité.
- Paramètres par défaut et constraints (AllowedValues) pour self-service.
- ChangeSets avant update :
aws cloudformation create-change-setpour preview diffs. - Drift detection :
aws cloudformation detect-stack-driftpour audits. - Versionnez templates en Git + CodePipeline pour CI/CD.
Erreurs courantes à éviter
- Dépendances manquantes : Toujours
DependsOnouCreationPolicypour ressources lentes (EC2). - IAM capabilities oubliées : Erreur ROLLBACK sans
--capabilities. - Région/AMI mismatch : Vérifiez AMI par
aws ec2 describe-images. - Buckets noms dupliqués : Global, forcez unicité avec !Sub.
Pour aller plus loin
- Docs officielles : AWS CloudFormation.
- Avancé : CDK (IaC en TS/Python) ou Terraform hybride.
- Formations Learni DevOps AWS pour certification Architect.
- Repo GitHub exemples : aws-samples/cloudformation-templates.