Introduction
AWS CloudFormation lets you define complete infrastructures as code. In 2026, requirements focus on managing distributed systems, high availability, and compliance. This expert tutorial covers advanced patterns: nested stacks, custom resources, dynamic conditions, and zero-downtime update strategies. You will learn to design maintainable and testable templates for critical production environments.
Prerequisites
- Strong skills in YAML and AWS IAM
- AWS CLI v2 installed and configured
- Basic knowledge of VPC, Lambda, RDS, and S3 services
- Node.js 20+ for custom resources
Basic Template with Parameters
AWSTemplateFormatVersion: '2010-09-09'
Description: 'VPC de base avec sous-réseaux publics et privés'
Parameters:
VpcCidr:
Type: String
Default: 10.0.0.0/16
Environment:
Type: String
AllowedValues: [dev, prod]
Resources:
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: !Ref VpcCidr
EnableDnsHostnames: true
EnableDnsSupport: true
Tags:
- Key: Environment
Value: !Ref EnvironmentThis template creates a configurable VPC. Parameters enable reuse across environments. Tags simplify filtering and billing.
Adding Subnets and Conditions
Resources:
PublicSubnet:
Type: AWS::EC2::Subnet
Condition: CreatePublic
Properties:
VpcId: !Ref VPC
CidrBlock: 10.0.1.0/24
MapPublicIpOnLaunch: true
Conditions:
CreatePublic: !Equals [!Ref Environment, prod]
Outputs:
VpcId:
Value: !Ref VPC
Export:
Name: !Sub '${AWS::StackName}-VpcId'Conditions prevent creating unnecessary resources in dev. The export enables sharing between stacks via Cross-Stack References.
Nested Stack for Modularity
Resources:
NetworkStack:
Type: AWS::CloudFormation::Stack
Properties:
TemplateURL: https://s3.amazonaws.com/my-bucket/network.yaml
Parameters:
VpcCidr: !Ref VpcCidr
Environment: !Ref Environment
AppStack:
Type: AWS::CloudFormation::Stack
DependsOn: NetworkStack
Properties:
TemplateURL: https://s3.amazonaws.com/my-bucket/app.yaml
Parameters:
VpcId: !GetAtt NetworkStack.Outputs.VpcIdNested stacks separate responsibilities. DependsOn guarantees creation order and avoids cross-reference errors.
Custom Resource with Lambda
Resources:
CustomFunction:
Type: AWS::Lambda::Function
Properties:
Handler: index.handler
Runtime: nodejs20.x
Code:
ZipFile: |
exports.handler = async (event) => {
// Custom provisioning logic
return { PhysicalResourceId: 'custom-123' };
};
CustomResource:
Type: Custom::MyResource
Properties:
ServiceToken: !GetAtt CustomFunction.ArnCustom resources extend CloudFormation for non-native resources. Always implement Create/Update/Delete event handling.
Secure Deployment Strategy
#!/bin/bash
set -euo pipefail
STACK_NAME="prod-infra-$(date +%Y%m%d)"
aws cloudformation deploy \
--template-file parent-stack.yaml \
--stack-name $STACK_NAME \
--capabilities CAPABILITY_IAM \
--parameter-overrides Environment=prod \
--no-fail-on-empty-changesetThe script uses strict protections (set -euo pipefail). CAPABILITY_IAM is mandatory for IAM resources. The dated name simplifies rollbacks.
Best Practices
- Always version templates in Git and use versioned S3 buckets
- Prefer nested stacks once the template exceeds 500 lines
- Use exported Outputs rather than physical references
- Enable termination protection on production stacks
- Implement tests with cfn-lint and taskcat before deployment
Common Mistakes to Avoid
- Forgetting DependsOn on resources with implicit dependencies
- Not handling updates for custom resources (risk of resource leaks)
- Using physical names instead of Refs (causes stack conflicts)
- Ignoring template size limits (max 1 MB compressed)
Further Reading
Deepen your skills with our advanced CloudFormation training.