Syntaxe et Templates CloudFormation
Introduction
CloudFormation utilise des templates en YAML ou JSON pour definir l'infrastructure. Ce chapitre couvre la syntaxe en detail et fournit des exemples pratiques de templates.
Structure d'un Template
# Structure complete d'un template CloudFormation
AWSTemplateFormatVersion: "2010-09-09"
Description: >
Description de ce que fait le template
(optionnel mais recommande)
Metadata:
# Informations supplementaires (optionnel)
Parameters:
# Valeurs d'entree personnalisables (optionnel)
Mappings:
# Correspondances cle-valeur statiques (optionnel)
Conditions:
# Logique conditionnelle (optionnel)
Transform:
# Macros ou SAM (optionnel)
Resources:
# Ressources AWS a creer (OBLIGATOIRE)
Outputs:
# Valeurs de sortie (optionnel)
Section Parameters
Syntaxe de Base
Parameters:
EnvironmentType:
Type: String
Default: dev
AllowedValues:
- dev
- staging
- prod
Description: Type d'environnement
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: Nom de la paire de cles SSH
VpcCidr:
Type: String
Default: 10.0.0.0/16
AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))$
Description: CIDR du VPC
Types de Parametres AWS
Parameters:
# Types de base
StringParam:
Type: String
NumberParam:
Type: Number
MinValue: 1
MaxValue: 100
ListParam:
Type: List<Number>
CommaListParam:
Type: CommaDelimitedList
# Types AWS specifiques
EC2KeyPair:
Type: AWS::EC2::KeyPair::KeyName
SecurityGroupId:
Type: AWS::EC2::SecurityGroup::Id
SubnetId:
Type: AWS::EC2::Subnet::Id
VpcId:
Type: AWS::EC2::VPC::Id
AMIId:
Type: AWS::EC2::Image::Id
AvailabilityZone:
Type: AWS::EC2::AvailabilityZone::Name
# Listes AWS
SubnetIds:
Type: List<AWS::EC2::Subnet::Id>
SecurityGroupIds:
Type: List<AWS::EC2::SecurityGroup::Id>
Section Resources
Syntaxe d'une Ressource
Resources:
NomLogiqueRessource:
Type: AWS::Service::Resource
Properties:
Property1: Value1
Property2: Value2
DependsOn:
- AutreRessource
DeletionPolicy: Retain | Delete | Snapshot
UpdateReplacePolicy: Retain | Delete | Snapshot
Condition: MaCondition
Exemples de Ressources Courantes
VPC
Resources:
MonVPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/16
EnableDnsHostnames: true
EnableDnsSupport: true
Tags:
- Key: Name
Value: MonVPC-Production
Subnet
PublicSubnet1:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref MonVPC
CidrBlock: 10.0.1.0/24
AvailabilityZone: !Select [0, !GetAZs '']
MapPublicIpOnLaunch: true
Tags:
- Key: Name
Value: Public-Subnet-1
Internet Gateway
InternetGateway:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
- Key: Name
Value: MonIGW
AttachGateway:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId: !Ref MonVPC
InternetGatewayId: !Ref InternetGateway
Security Group
WebSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Security group pour serveur web
VpcId: !Ref MonVPC
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
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 10.0.0.0/8
Tags:
- Key: Name
Value: Web-SG
EC2 Instance
WebServer:
Type: AWS::EC2::Instance
Properties:
InstanceType: !Ref InstanceType
ImageId: !Ref AMIId
KeyName: !Ref KeyPairName
SubnetId: !Ref PublicSubnet1
SecurityGroupIds:
- !Ref WebSecurityGroup
Tags:
- Key: Name
Value: WebServer-1
UserData:
Fn::Base64: !Sub |
#!/bin/bash
yum update -y
yum install -y httpd
systemctl start httpd
systemctl enable httpd
echo "Hello from ${AWS::StackName}" > /var/www/html/index.html
Fonctions Intrinseques
Ref
# Reference un parametre ou une ressource
VpcId: !Ref MonVPC
InstanceType: !Ref ParametreInstanceType
# Syntaxe longue
VpcId:
Ref: MonVPC
GetAtt
# Obtenir un attribut d'une ressource
Outputs:
InstancePublicIP:
Value: !GetAtt WebServer.PublicIp
SecurityGroupId:
Value: !GetAtt WebSecurityGroup.GroupId
# Syntaxe longue
Value:
Fn::GetAtt:
- WebServer
- PublicIp
Sub (Substitution)
# Substitution de variables
UserData:
Fn::Base64: !Sub |
#!/bin/bash
echo "Region: ${AWS::Region}"
echo "Stack: ${AWS::StackName}"
echo "Instance: ${WebServer}"
# Avec variables personnalisees
Value: !Sub
- "arn:aws:s3:::${BucketName}/*"
- BucketName: !Ref MonBucket
Join
# Joindre des elements avec un separateur
Value: !Join
- ","
- - subnet-12345
- subnet-67890
- subnet-abcde
# Resultat: "subnet-12345,subnet-67890,subnet-abcde"
# Syntaxe courte
Value: !Join [",", [!Ref Subnet1, !Ref Subnet2]]
Select
# Selectionner un element d'une liste
AvailabilityZone: !Select
- 0
- !GetAZs ''
# Selectionne la premiere AZ de la region
Split
# Diviser une chaine
Value: !Select
- 0
- !Split [",", "a,b,c"]
# Resultat: "a"
If (Condition)
Conditions:
IsProd: !Equals [!Ref Environment, prod]
Resources:
MyInstance:
Type: AWS::EC2::Instance
Properties:
InstanceType: !If
- IsProd
- m5.large
- t3.micro
GetAZs
# Obtenir les AZ d'une region
AvailabilityZones: !GetAZs '' # Region courante
AvailabilityZones: !GetAZs 'us-east-1' # Region specifique
Section Conditions
Parameters:
Environment:
Type: String
AllowedValues: [dev, staging, prod]
Conditions:
IsProd: !Equals [!Ref Environment, prod]
IsNotProd: !Not [!Equals [!Ref Environment, prod]]
IsProdOrStaging: !Or
- !Equals [!Ref Environment, prod]
- !Equals [!Ref Environment, staging]
IsProdAndMultiAZ: !And
- !Equals [!Ref Environment, prod]
- !Equals [!Ref MultiAZ, true]
Resources:
ProdOnlyResource:
Type: AWS::EC2::Instance
Condition: IsProd # Cree seulement si IsProd est true
Properties:
# ...
Section Mappings
Mappings:
RegionAMI:
us-east-1:
HVM64: ami-0123456789abcdef0
HVM32: ami-0123456789abcdef1
us-west-2:
HVM64: ami-abcdef0123456789a
HVM32: ami-abcdef0123456789b
eu-west-1:
HVM64: ami-fedcba9876543210f
HVM32: ami-fedcba9876543210e
EnvironmentConfig:
dev:
InstanceType: t3.micro
MinSize: 1
MaxSize: 2
prod:
InstanceType: m5.large
MinSize: 2
MaxSize: 10
Resources:
MyInstance:
Type: AWS::EC2::Instance
Properties:
ImageId: !FindInMap [RegionAMI, !Ref "AWS::Region", HVM64]
InstanceType: !FindInMap [EnvironmentConfig, !Ref Environment, InstanceType]
Section Outputs
Outputs:
VpcId:
Description: ID du VPC cree
Value: !Ref MonVPC
Export:
Name: !Sub "${AWS::StackName}-VpcId"
PublicSubnetId:
Description: ID du subnet public
Value: !Ref PublicSubnet1
Export:
Name: !Sub "${AWS::StackName}-PublicSubnetId"
WebServerPublicIP:
Description: IP publique du serveur web
Value: !GetAtt WebServer.PublicIp
Condition: IsProd # Output conditionnel
WebsiteURL:
Description: URL du site web
Value: !Sub "http://${WebServer.PublicDnsName}"
Template Complet Exemple
AWSTemplateFormatVersion: "2010-09-09"
Description: Infrastructure web simple avec VPC, EC2 et Security Group
Parameters:
Environment:
Type: String
Default: dev
AllowedValues: [dev, staging, prod]
Description: Environnement de deploiement
InstanceType:
Type: String
Default: t3.micro
AllowedValues: [t3.micro, t3.small, t3.medium]
KeyName:
Type: AWS::EC2::KeyPair::KeyName
Description: Paire de cles SSH
Mappings:
RegionAMI:
us-east-1:
AMI: ami-0123456789abcdef0
ca-central-1:
AMI: ami-0abcdef1234567890
Conditions:
IsProd: !Equals [!Ref Environment, prod]
Resources:
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/16
EnableDnsHostnames: true
Tags:
- Key: Name
Value: !Sub "${Environment}-VPC"
PublicSubnet:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock: 10.0.1.0/24
MapPublicIpOnLaunch: true
Tags:
- Key: Name
Value: !Sub "${Environment}-Public-Subnet"
InternetGateway:
Type: AWS::EC2::InternetGateway
AttachGateway:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId: !Ref VPC
InternetGatewayId: !Ref InternetGateway
RouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
PublicRoute:
Type: AWS::EC2::Route
DependsOn: AttachGateway
Properties:
RouteTableId: !Ref RouteTable
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref InternetGateway
SubnetRouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PublicSubnet
RouteTableId: !Ref RouteTable
SecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Web Server Security Group
VpcId: !Ref VPC
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 0.0.0.0/0
WebServer:
Type: AWS::EC2::Instance
Properties:
InstanceType: !If [IsProd, t3.small, !Ref InstanceType]
ImageId: !FindInMap [RegionAMI, !Ref "AWS::Region", AMI]
KeyName: !Ref KeyName
SubnetId: !Ref PublicSubnet
SecurityGroupIds:
- !Ref SecurityGroup
Tags:
- Key: Name
Value: !Sub "${Environment}-WebServer"
UserData:
Fn::Base64: !Sub |
#!/bin/bash
yum update -y
yum install -y httpd
systemctl start httpd
echo "<h1>Env: ${Environment}</h1>" > /var/www/html/index.html
Outputs:
VpcId:
Value: !Ref VPC
Export:
Name: !Sub "${AWS::StackName}-VpcId"
WebServerIP:
Value: !GetAtt WebServer.PublicIp
Description: IP publique du serveur
WebsiteURL:
Value: !Sub "http://${WebServer.PublicDnsName}"
Description: URL du site web
Resume
- Un template a une structure definie avec Resources obligatoire
- Parameters permettent la personnalisation au deploiement
- Fonctions intrinseques (!Ref, !GetAtt, !Sub, etc.) pour referencer
- Conditions pour creer des ressources conditionnellement
- Mappings pour des valeurs statiques par region/environnement
- Outputs pour exporter des valeurs
Prochaine section : Quiz de Validation