AWS CloudFormation
AWS CloudFormation is a service that helps you model and set up your Amazon Web Services resources so you can spend less time managing those resources and more time focusing on your applications that run in AWS. You create a template that describes all the AWS resources that you want, and CloudFormation takes care of provisioning and configuring those resources for you.
What is CloudFormation?
CloudFormation is AWS's native Infrastructure as Code (IaC) service that allows you to define your cloud infrastructure using JSON or YAML templates. It provides a common language for describing and provisioning all the infrastructure resources in your cloud environment.
Key Features
- Template-Based: Define infrastructure using JSON or YAML templates
- Declarative: Describe what you want, not how to create it
- AWS Native: Deep integration with all AWS services
- Stack Management: Group related resources into manageable stacks
- Rollback Capability: Automatic rollback on deployment failures
- Change Sets: Preview changes before applying them
- Cross-Stack References: Share resources between stacks
Core Concepts
1. Templates
CloudFormation templates are JSON or YAML files that describe your AWS resources:
# template.yaml
AWSTemplateFormatVersion: "2010-09-09"
Description: "Simple EC2 instance"
Parameters:
InstanceType:
Type: String
Default: t2.micro
AllowedValues:
- t2.micro
- t2.small
- t2.medium
Resources:
MyEC2Instance:
Type: AWS::EC2::Instance
Properties:
ImageId: ami-0c02fb55956c7d316
InstanceType: !Ref InstanceType
Tags:
- Key: Name
Value: MyInstance
Outputs:
InstanceId:
Description: Instance ID of the EC2 instance
Value: !Ref MyEC2Instance
Export:
Name: MyInstanceId
2. Stacks
A stack is a collection of AWS resources that you can manage as a single unit:
# Create a stack
aws cloudformation create-stack \
--stack-name my-stack \
--template-body file://template.yaml
# Update a stack
aws cloudformation update-stack \
--stack-name my-stack \
--template-body file://template.yaml
# Delete a stack
aws cloudformation delete-stack \
--stack-name my-stack
3. Parameters
Make templates reusable by accepting input values:
Parameters:
Environment:
Type: String
Default: dev
AllowedValues:
- dev
- staging
- prod
Description: Environment name
VpcCIDR:
Type: String
Default: 10.0.0.0/16
Description: CIDR block for VPC
4. Conditions
Control resource creation based on parameter values:
Conditions:
CreateProdResources: !Equals [!Ref Environment, prod]
Resources:
ProdDatabase:
Type: AWS::RDS::DBInstance
Condition: CreateProdResources
Properties:
DBInstanceClass: db.r5.large
Engine: mysql
5. Mappings
Create lookup tables for values:
Mappings:
RegionMap:
us-east-1:
AMI: ami-0c02fb55956c7d316
us-west-2:
AMI: ami-0c02fb55956c7d316
eu-west-1:
AMI: ami-0c02fb55956c7d316
Resources:
MyInstance:
Type: AWS::EC2::Instance
Properties:
ImageId: !FindInMap [RegionMap, !Ref AWS::Region, AMI]
Template Structure
Basic Template Format
AWSTemplateFormatVersion: "2010-09-09"
Description: "Template description"
Parameters:
# Input parameters
Conditions:
# Conditional logic
Mappings:
# Lookup tables
Resources:
# AWS resources
Outputs:
# Stack outputs
Intrinsic Functions
CloudFormation provides built-in functions for dynamic values:
Resources:
MyBucket:
Type: AWS::S3::Bucket
Properties:
BucketName: !Sub "${AWS::StackName}-bucket-${AWS::AccountId}"
WebsiteConfiguration:
IndexDocument: index.html
ErrorDocument: error.html
MyInstance:
Type: AWS::EC2::Instance
Properties:
ImageId: !Ref LatestAmi
UserData:
Fn::Base64: !Sub |
#!/bin/bash
yum update -y
yum install -y httpd
systemctl start httpd
systemctl enable httpd
Common Intrinsic Functions
1. Ref
References parameters, resources, or pseudo parameters:
!Ref MyParameter
!Ref AWS::Region
!Ref MyEC2Instance
2. GetAtt
Gets attributes from resources:
!GetAtt MyEC2Instance.PublicIp
!GetAtt MyLoadBalancer.DNSName
3. Sub
Substitutes variables in strings:
!Sub 'https://${MyBucket}.s3.amazonaws.com'
!Sub
- 'Hello ${Name}'
- Name: !Ref UserName
4. Join
Joins strings with a delimiter:
!Join [",", [!Ref Param1, !Ref Param2, !Ref Param3]]
5. Select
Selects an element from a list:
!Select [0, !GetAZs !Ref AWS::Region]
Advanced Features
1. Nested Stacks
Break complex templates into smaller, manageable pieces:
Resources:
NetworkStack:
Type: AWS::CloudFormation::Stack
Properties:
TemplateURL: https://s3.amazonaws.com/bucket/network.yaml
Parameters:
VpcCIDR: 10.0.0.0/16
2. Cross-Stack References
Share resources between stacks:
# Stack A - Export
Outputs:
VpcId:
Value: !Ref MyVPC
Export:
Name: !Sub "${AWS::StackName}-VPC-ID"
# Stack B - Import
Resources:
MySubnet:
Type: AWS::EC2::Subnet
Properties:
VpcId: !ImportValue "NetworkStack-VPC-ID"
3. Custom Resources
Extend CloudFormation with custom logic:
Resources:
CustomResource:
Type: Custom::MyCustomResource
Properties:
ServiceToken: !GetAtt CustomResourceFunction.Arn
Parameter1: value1
Parameter2: value2
4. Stack Sets
Deploy stacks across multiple accounts and regions:
aws cloudformation create-stack-set \
--stack-set-name my-stack-set \
--template-body file://template.yaml \
--capabilities CAPABILITY_IAM
Best Practices
1. Template Design
- Use parameters for configurable values
- Implement proper validation for parameters
- Use conditions for optional resources
- Organize resources logically
- Use meaningful resource names
2. Security
- Use IAM roles and policies properly
- Implement least privilege access
- Use AWS Secrets Manager for sensitive data
- Enable CloudTrail for audit logging
- Use parameter constraints
3. Error Handling
- Implement proper rollback triggers
- Use change sets for preview
- Test templates in dev environment first
- Use stack policies for protection
- Monitor stack events
4. Performance
- Use nested stacks for large templates
- Implement proper dependencies
- Use cross-stack references efficiently
- Optimize template size
- Use stack sets for multi-account deployments
Common Use Cases
1. Web Application Stack
Resources:
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/16
PublicSubnet:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock: 10.0.1.0/24
AvailabilityZone: !Select [0, !GetAZs !Ref AWS::Region]
InternetGateway:
Type: AWS::EC2::InternetGateway
AttachGateway:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId: !Ref VPC
InternetGatewayId: !Ref InternetGateway
PublicRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
DefaultPublicRoute:
Type: AWS::EC2::Route
DependsOn: AttachGateway
Properties:
RouteTableId: !Ref PublicRouteTable
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref InternetGateway
WebServer:
Type: AWS::EC2::Instance
Properties:
ImageId: ami-0c02fb55956c7d316
InstanceType: t2.micro
SubnetId: !Ref PublicSubnet
SecurityGroupIds:
- !Ref WebServerSecurityGroup
2. Database Stack
Resources:
DatabaseSubnetGroup:
Type: AWS::RDS::DBSubnetGroup
Properties:
DBSubnetGroupDescription: Subnet group for RDS
SubnetIds:
- !Ref PrivateSubnet1
- !Ref PrivateSubnet2
Database:
Type: AWS::RDS::DBInstance
Properties:
DBInstanceIdentifier: my-database
DBName: myapp
DBInstanceClass: db.t3.micro
Engine: mysql
EngineVersion: "8.0"
MasterUsername: admin
MasterUserPassword: !Ref DatabasePassword
DBSubnetGroupName: !Ref DatabaseSubnetGroup
VPCSecurityGroups:
- !Ref DatabaseSecurityGroup
CloudFormation vs Other Tools
Feature | CloudFormation | Terraform | OpenTofu | Pulumi |
---|---|---|---|---|
Language | JSON/YAML | HCL | HCL | Python/TypeScript/Go |
Provider | AWS Only | Multi-Cloud | Multi-Cloud | Multi-Cloud |
State Management | AWS Managed | Local/Remote | Local/Remote | Cloud/File |
Cost | Free | Free | Free | Free/Paid |
Learning Curve | Medium | Medium | Medium | Hard |
AWS Integration | Native | Good | Good | Good |
When to Use CloudFormation
Choose CloudFormation when:
- You're working exclusively with AWS
- You need deep AWS service integration
- You want AWS-managed state and operations
- You prefer JSON/YAML over other languages
- You need AWS support and documentation
- You're using AWS Organizations and Stack Sets
Consider alternatives when:
- You need multi-cloud support
- You want more flexible programming languages
- You need advanced state management features
- You want to avoid vendor lock-in
- You need more sophisticated templating
CLI Commands
Basic Operations
# Create stack
aws cloudformation create-stack \
--stack-name my-stack \
--template-body file://template.yaml \
--parameters ParameterKey=KeyPairName,ParameterValue=MyKeyPair
# Update stack
aws cloudformation update-stack \
--stack-name my-stack \
--template-body file://template.yaml
# Delete stack
aws cloudformation delete-stack --stack-name my-stack
# Describe stack
aws cloudformation describe-stacks --stack-name my-stack
# List stacks
aws cloudformation list-stacks
Change Sets
# Create change set
aws cloudformation create-change-set \
--stack-name my-stack \
--change-set-name my-change-set \
--template-body file://template.yaml
# Execute change set
aws cloudformation execute-change-set \
--change-set-name my-change-set
Monitoring and Troubleshooting
1. Stack Events
# View stack events
aws cloudformation describe-stack-events --stack-name my-stack
2. Stack Drift Detection
# Detect drift
aws cloudformation detect-stack-drift --stack-name my-stack
# Get drift results
aws cloudformation describe-stack-drift-detection-status \
--stack-drift-detection-id drift-detection-id
3. CloudWatch Integration
- Stack events are automatically sent to CloudWatch
- Set up alarms for stack failures
- Monitor stack resource metrics
- Use CloudWatch Logs for custom resource debugging