AWS CloudFormation Skill
Create and manage infrastructure as code with CloudFormation.
Quick Reference
| Attribute | Value | |-----------|-------| | AWS Service | CloudFormation | | Complexity | Medium-High | | Est. Time | 10-60 min | | Prerequisites | IAM permissions |
Parameters
Required
| Parameter | Type | Description | Validation | |-----------|------|-------------|------------| | stack_name | string | Stack name | ^[a-zA-Z][-a-zA-Z0-9]{0,127}$ | | template_path | string | Template file path | Valid YAML/JSON |
Optional
| Parameter | Type | Default | Description | |-----------|------|---------|-------------| | parameters | object | {} | Stack parameters | | capabilities | array | [] | CAPABILITY_IAM, etc. | | tags | object | {} | Resource tags | | termination_protection | bool | false | Prevent deletion | | rollback_on_failure | bool | true | Rollback on error |
Template Structure
AWSTemplateFormatVersion: '2010-09-09'
Description: 'Production VPC with 3-tier architecture'
Parameters:
Environment:
Type: String
AllowedValues: [dev, staging, prod]
Mappings:
RegionMap:
us-east-1:
AMI: ami-12345678
Conditions:
IsProd: !Equals [!Ref Environment, prod]
Resources:
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/16
Tags:
- Key: Name
Value: !Sub ${Environment}-vpc
Outputs:
VPCId:
Value: !Ref VPC
Export:
Name: !Sub ${Environment}-VPCId
Implementation
Deploy Stack
# Validate template
aws cloudformation validate-template \
--template-body file://template.yaml
# Create stack
aws cloudformation create-stack \
--stack-name my-stack \
--template-body file://template.yaml \
--parameters ParameterKey=Environment,ParameterValue=prod \
--capabilities CAPABILITY_IAM CAPABILITY_NAMED_IAM \
--tags Key=Environment,Value=Production \
--enable-termination-protection
# Wait for completion
aws cloudformation wait stack-create-complete --stack-name my-stack
Update Stack
# Create change set (preview changes)
aws cloudformation create-change-set \
--stack-name my-stack \
--change-set-name my-changes \
--template-body file://template.yaml \
--parameters ParameterKey=Environment,ParameterValue=prod
# Review changes
aws cloudformation describe-change-set \
--stack-name my-stack \
--change-set-name my-changes
# Execute change set
aws cloudformation execute-change-set \
--stack-name my-stack \
--change-set-name my-changes
Nested Stacks Pattern
Resources:
VPCStack:
Type: AWS::CloudFormation::Stack
Properties:
TemplateURL: https://s3.amazonaws.com/bucket/vpc.yaml
Parameters:
Environment: !Ref Environment
DatabaseStack:
Type: AWS::CloudFormation::Stack
DependsOn: VPCStack
Properties:
TemplateURL: https://s3.amazonaws.com/bucket/rds.yaml
Parameters:
VPCId: !GetAtt VPCStack.Outputs.VPCId
Troubleshooting
Common Issues
| Symptom | Cause | Solution | |---------|-------|----------| | CREATE_FAILED | Resource error | Check events for details | | UPDATE_ROLLBACK | Update failed | Review change set | | DELETE_FAILED | Resource in use | Remove dependencies | | ROLLBACK_COMPLETE | Creation failed | Delete and fix |
Debug Checklist
- [ ] Template valid (
validate-template)? - [ ] Required capabilities specified?
- [ ] Parameters have valid values?
- [ ] IAM has required permissions?
- [ ] Resource dependencies correct?
- [ ] No circular references?
Stack Events Analysis
# Get stack events
aws cloudformation describe-stack-events \
--stack-name my-stack \
--query 'StackEvents[?ResourceStatus==`CREATE_FAILED`]'
Common Errors
Resource handler returned message: ... → Provider-specific error
Circular dependency between resources → Use DependsOn carefully
Export ... cannot be updated → Update dependent stacks first
Template format error → Check YAML syntax
Best Practices
- Use Change Sets: Always preview before updating
- Enable Termination Protection: For production stacks
- Use Nested Stacks: For reusable components
- Export Outputs: For cross-stack references
- Use Stack Policies: Protect critical resources
- Version Templates: Store in Git
Test Template
def test_cloudformation_template():
# Arrange
template_body = open('template.yaml').read()
# Act - Validate
response = cfn.validate_template(TemplateBody=template_body)
# Assert
assert 'Parameters' in response
assert response['Capabilities'] == ['CAPABILITY_IAM']
# Act - Create stack (dry run)
# Use change set with no execute for testing
Assets
assets/vpc-template.yaml- Production VPC template