Skip to content
Learni
Voir tous les tutoriels
AWS

Comment déployer une stack AWS CloudFormation en 2026

Read in English

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 policy AdministratorAccess pour tests).
  • AWS CLI v2 installée et configurée (aws configure avec access key).
  • Région AWS par défaut : us-east-1 (modifiable via --region).
  • Connaissances de base en YAML et networking AWS.
  • Outil cfn-lint pour validation : pip install cfn-lint.

Template S3 bucket basique

s3-bucket.yaml
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

vpc-network.yaml
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

ec2-instance.yaml
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.PublicIp

Intè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

full-stack.yaml
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

deploy.sh
#!/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-set pour preview diffs.
  • Drift detection : aws cloudformation detect-stack-drift pour audits.
  • Versionnez templates en Git + CodePipeline pour CI/CD.

Erreurs courantes à éviter

  • Dépendances manquantes : Toujours DependsOn ou CreationPolicy pour 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