'"Creates Infrastructure as Code templates with CloudFormation for reproducible"
Scanned 9/4/2026
Install to Claude Code
npx -y skills add paulpas/agent-skill-router --skill aws-cloudformation --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Aws Cloudformation?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/paulpas-aws-cloudformation)More formats (shields.io, HTML) on the badges page.
---
name: aws-cloudformation
compatibility: opencode
completeness: 95
content-types:
- guidance
- examples
- do-dont
- config
description: '"Creates Infrastructure as Code templates with CloudFormation for reproducible"
versioned, automated deployments of entire AWS infrastructure stacks.'
license: MIT
maturity: stable
metadata:
domain: cncf
output-format: manifests
related-skills: aws-ec2, aws-iam, aws-rds, aws-s3
role: reference
scope: infrastructure
triggers: cloudformation, infrastructure as code, iac, cloudformation template,
stack, aws template, yaml, json
archetypes:
- educational
- strategic
anti_triggers:
- brainstorming
- vague ideation
- non-containerized architecture
response_profile:
verbosity: medium
directive_strength: low
abstraction_level: strategic
version: "1.0.0"
---
# CloudFormation
Design and deploy complete AWS infrastructure as code using templates, enabling version control, repeatable deployments, and automated stack management.
## TL;DR Checklist
- [ ] Use YAML format for templates (more readable than JSON)
- [ ] Parameterize templates for reusability across environments
- [ ] Use Outputs to expose important resource values
- [ ] Implement change sets before updating production stacks
- [ ] Version control all templates in Git
- [ ] Use DependsOn for explicit resource dependencies
- [ ] Implement rollback on update failure
- [ ] Create separate templates for modularity (nested stacks)
- [ ] Use stack policies to prevent accidental resource deletion
- [ ] Tag all resources for cost allocation and management
---
## When to Use
Use CloudFormation when:
- Infrastructure needs to be reproducible across environments
- Requiring version control for infrastructure changes
- Automating infrastructure provisioning and updates
- Building reusable templates for common architectures
- Implementing infrastructure as code (IaC) practices
- Coordinating complex resource dependencies
---
## When NOT to Use
Avoid CloudFormation when:
- Building one-off infrastructure (manual console is faster)
- Requiring rapid prototyping (AWS CDK may be better)
- Managing third-party services (use Terraform instead)
- Working with non-AWS resources exclusively
---
## Purpose and Use Cases
**Primary Purpose:** Provide declarative infrastructure as code enabling version-controlled, repeatable, automated deployments of entire AWS infrastructure stacks.
**Common Use Cases:**
1. **Environment Templates** — Dev, staging, production environments from same template
2. **Disaster Recovery** — Rebuild entire infrastructure in secondary region
3. **Multi-Account Deployments** — Deploy stack across multiple AWS accounts
4. **Blue-Green Deployments** — Create new stack, test, then switch traffic
5. **Infrastructure Automation** — CI/CD pipelines deploy infrastructure changes
6. **Compliance and Governance** — Enforce architecture standards via templates
---
## Architecture Design Patterns
### Pattern 1: Modular Multi-AZ Web Application Stack
```yaml
AWSTemplateFormatVersion: '2010-09-09'
Description: Production web application stack with VPC, RDS, and ALB
Metadata:
AWS::CloudFormation::Interface:
ParameterGroups:
- Label:
default: Network Configuration
Parameters:
- VPCCidr
- Environment
- EnableEncryption
- Label:
default: Database Configuration
Parameters:
- DBInstanceClass
- DBAllocatedStorage
Parameters:
Environment:
Type: String
Default: production
AllowedValues:
- development
- staging
- production
Description: Environment name
VPCCidr:
Type: String
Default: 10.0.0.0/16
Description: CIDR block for VPC
DBInstanceClass:
Type: String
Default: db.r6i.2xlarge
Description: Database instance type
AllowedValues:
- db.t3.medium
- db.r6i.xlarge
- db.r6i.2xlarge
- db.r6i.4xlarge
DBAllocatedStorage:
Type: Number
Default: 100
MinValue: 20
MaxValue: 1000
Description: Database storage in GB
EnableEncryption:
Type: String
Default: 'true'
AllowedValues:
- 'true'
- 'false'
Description: Enable encryption at rest
Conditions:
IsProduction: !Equals [!Ref Environment, production]
ShouldEncrypt: !Equals [!Ref EnableEncryption, 'true']
Resources:
# ==================== VPC ====================
ProductionVPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: !Ref VPCCidr
EnableDnsHostnames: true
EnableDnsSupport: true
Tags:
- Key: Name
Value: !Sub '${Environment}-vpc'
# Public Subnets
PublicSubnet1:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref ProductionVPC
CidrBlock: !Select [0, !Cidr [!Ref VPCCidr, 6, 8]]
AvailabilityZone: !Select [0, !GetAZs '']
MapPublicIpOnLaunch: true
Tags:
- Key: Name
Value: !Sub '${Environment}-public-subnet-1'
PublicSubnet2:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref ProductionVPC
CidrBlock: !Select [1, !Cidr [!Ref VPCCidr, 6, 8]]
AvailabilityZone: !Select [1, !GetAZs '']
MapPublicIpOnLaunch: true
Tags:
- Key: Name
Value: !Sub '${Environment}-public-subnet-2'
# Private Subnets
PrivateSubnet1:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref ProductionVPC
CidrBlock: !Select [2, !Cidr [!Ref VPCCidr, 6, 8]]
AvailabilityZone: !Select [0, !GetAZs '']
Tags:
- Key: Name
Value: !Sub '${Environment}-private-subnet-1'
PrivateSubnet2:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref ProductionVPC
CidrBlock: !Select [3, !Cidr [!Ref VPCCidr, 6, 8]]
AvailabilityZone: !Select [1, !GetAZs '']
Tags:
- Key: Name
Value: !Sub '${Environment}-private-subnet-2'
# Database Subnets
DBSubnet1:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref ProductionVPC
CidrBlock: !Select [4, !Cidr [!Ref VPCCidr, 6, 8]]
AvailabilityZone: !Select [0, !GetAZs '']
Tags:
- Key: Name
Value: !Sub '${Environment}-db-subnet-1'
DBSubnet2:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref ProductionVPC
CidrBlock: !Select [5, !Cidr [!Ref VPCCidr, 6, 8]]
AvailabilityZone: !Select [1, !GetAZs '']
Tags:
- Key: Name
Value: !Sub '${Environment}-db-subnet-2'
# Internet Gateway
InternetGateway:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
- Key: Name
Value: !Sub '${Environment}-igw'
AttachGateway:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId: !Ref ProductionVPC
InternetGatewayId: !Ref InternetGateway
# NAT Gateways
NATGatewayEIP1:
Type: AWS::EC2::EIP
DependsOn: AttachGateway
Properties:
Domain: vpc
Tags:
- Key: Name
Value: !Sub '${Environment}-nat-eip-1'
NATGateway1:
Type: AWS::EC2::NatGateway
Properties:
AllocationId: !GetAtt NATGatewayEIP1.AllocationId
SubnetId: !Ref PublicSubnet1
# ==================== SECURITY ====================
ALBSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: ALB security group
VpcId: !Ref ProductionVPC
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
Tags:
- Key: Name
Value: !Sub '${Environment}-alb-sg'
AppSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Application security group
VpcId: !Ref ProductionVPC
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 8080
ToPort: 8080
SourceSecurityGroupId: !Ref ALBSecurityGroup
Tags:
- Key: Name
Value: !Sub '${Environment}-app-sg'
DBSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Database security group
VpcId: !Ref ProductionVPC
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 5432
ToPort: 5432
SourceSecurityGroupId: !Ref AppSecurityGroup
Tags:
- Key: Name
Value: !Sub '${Environment}-db-sg'
# ==================== DATABASE ====================
DBSubnetGroup:
Type: AWS::RDS::DBSubnetGroup
Properties:
DBSubnetGroupDescription: Database subnet group
SubnetIds:
- !Ref DBSubnet1
- !Ref DBSubnet2
Tags:
- Key: Name
Value: !Sub '${Environment}-db-subnet-group'
Database:
Type: AWS::RDS::DBInstance
DeletionPolicy: Snapshot
Properties:
DBInstanceIdentifier: !Sub '${Environment}-db'
Engine: postgres
EngineVersion: '14.7'
DBInstanceClass: !Ref DBInstanceClass
AllocatedStorage: !Ref DBAllocatedStorage
StorageType: gp3
StorageEncrypted: !If [ShouldEncrypt, true, false]
MasterUsername: admin
MasterUserPassword: !Sub '{{resolve:secretsmanager:${Environment}/db-password:SecretString:password}}'
DBSubnetGroupName: !Ref DBSubnetGroup
VPCSecurityGroups:
- !Ref DBSecurityGroup
MultiAZ: !If [IsProduction, true, false]
BackupRetentionPeriod: !If [IsProduction, 30, 7]
PreferredBackupWindow: '03:00-04:00'
PreferredMaintenanceWindow: 'sun:04:00-sun:05:00'
DeletionProtection: !If [IsProduction, true, false]
Tags:
- Key: Name
Value: !Sub '${Environment}-database'
Outputs:
VPCId:
Description: VPC ID
Value: !Ref ProductionVPC
Export:
Name: !Sub '${Environment}-VPC-ID'
PrivateSubnet1Id:
Description: Private subnet 1 ID
Value: !Ref PrivateSubnet1
Export:
Name: !Sub '${Environment}-PrivateSubnet1-ID'
PrivateSubnet2Id:
Description: Private subnet 2 ID
Value: !Ref PrivateSubnet2
Export:
Name: !Sub '${Environment}-PrivateSubnet2-ID'
DatabaseEndpoint:
Description: Database endpoint address
Value: !GetAtt Database.Endpoint.Address
Export:
Name: !Sub '${Environment}-Database-Endpoint'
DBSecurityGroupId:
Description: Database security group ID
Value: !Ref DBSecurityGroup
Export:
Name: !Sub '${Environment}-DBSecurityGroup-ID'
ALBSecurityGroupId:
Description: ALB security group ID
Value: !Ref ALBSecurityGroup
Export:
Name: !Sub '${Environment}-ALBSecurityGroup-ID'
```
**Key Elements:**
- Parameterized for environment reusability
- Conditional resources (production vs. development)
- Multi-AZ high availability
- Exports for cross-stack references
- Comprehensive Outputs for integration
- Clear resource naming and tagging
### Pattern 2: Change Set and Stack Policy for Safety
```yaml
# Create change set before updating stack
aws cloudformation create-change-set \
--stack-name prod-stack \
--change-set-name prod-stack-update-$(date +%s) \
--template-body file://template.yaml \
--parameters ParameterKey=Environment,ParameterValue=production \
--change-set-type UPDATE
# Review change set
aws cloudformation describe-change-set \
--stack-name prod-stack \
--change-set-name prod-stack-update-1234567890
# Execute change set
aws cloudformation execute-change-set \
--stack-name prod-stack \
--change-set-name prod-stack-update-1234567890
# Stack Policy to prevent accidental deletion
{
"Statement": [
{
"Effect": "Deny",
"Principal": "*",
"Action": [
"cloudformation:Delete",
"cloudformation:Update"
],
"Resource": "LogicalResourceId/Database",
"Condition": {
"StringNotLike": {
"aws:PrincipalArn": "arn:aws:iam::123456789012:role/admin"
}
}
},
{
"Effect": "Allow",
"Principal": "*",
"Action": "cloudformation:Update",
"Resource": "*"
}
]
}
```
**Key Elements:**
- Change sets for safe updates (review before execute)
- Stack policies for protection
- Rollback on failure automatic
- CloudTrail logs all stack operations
### Pattern 3: Nested Stacks for Modularity
```yaml
# Parent stack references nested stacks
Resources:
NetworkingStack:
Type: AWS::CloudFormation::Stack
Properties:
StackName: !Sub '${Environment}-networking'
TemplateURL: https://s3.amazonaws.com/cf-templates/networking.yaml
Parameters:
VPCCidr: !Ref VPCCidr
Environment: !Ref Environment
DatabaseStack:
Type: AWS::CloudFormation::Stack
DependsOn: NetworkingStack
Properties:
StackName: !Sub '${Environment}-database'
TemplateURL: https://s3.amazonaws.com/cf-templates/database.yaml
Parameters:
VPCId: !GetAtt NetworkingStack.Outputs.VPCId
DBSubnetGroup: !GetAtt NetworkingStack.Outputs.DBSubnetGroupName
ApplicationStack:
Type: AWS::CloudFormation::Stack
DependsOn: DatabaseStack
Properties:
StackName: !Sub '${Environment}-application'
TemplateURL: https://s3.amazonaws.com/cf-templates/application.yaml
Parameters:
VPCId: !GetAtt NetworkingStack.Outputs.VPCId
DatabaseEndpoint: !GetAtt DatabaseStack.Outputs.DatabaseEndpoint
Outputs:
ApplicationURL:
Value: !GetAtt ApplicationStack.Outputs.ApplicationURL
```
**Key Elements:**
- Modular nested stacks for separation of concerns
- DependsOn for ordered stack creation
- Cross-stack outputs via GetAtt
- Reusable templates for common infrastructure
---
## Integration Approaches
### 1. Integration with CodePipeline
CloudFormation + CodePipeline enables:
- Automated infrastructure deployments
- Change sets in CI/CD pipeline
- Approval workflows before production
- Rollback on pipeline failures
### 2. Integration with Service Catalog
Service Catalog + CloudFormation:
- Self-service infrastructure provisioning
- Governance via approved templates
- End-user simplicity with pre-configured options
- Cost tracking per product
### 3. Integration with StackSets
StackSets enable:
- Deploy stack to multiple accounts/regions
- Centralized management
- Automatic updates across deployment targets
- Role-based permissions
### 4. Integration with Systems Manager
Systems Manager + CloudFormation:
- Document-based automation
- Parameter store for template values
- Automation runbooks for post-deployment
- Configuration management
---
## Common Pitfalls
### ❌ Pitfall 1: Hardcoded Values in Templates
**Problem:** Values not reusable; must edit template for each environment.
**Solution:**
- Use Parameters for all environment-specific values
- Use Pseudo Parameters for account/region
- Parameterize instance types, storage, retention
### ❌ Pitfall 2: Tight Coupling Between Stacks
**Problem:** Stacks depend on internal resource IDs; hard to update independently.
**Solution:**
- Use Outputs and cross-stack references
- Decouple stacks functionally (networking, database, app)
- Use nested stacks for logical grouping
### ❌ Pitfall 3: No Change Set Review
**Problem:** Update stack directly; unexpected changes cause outages.
**Solution:**
- Always use change sets for production
- Review changes before execution
- Enable termination protection for critical stacks
### ❌ Pitfall 4: Unversioned Templates
**Problem:** Lose history of infrastructure changes; rollback difficult.
**Solution:**
- Version control all templates in Git
- Use commit messages to document changes
- Tag releases in Git matching stack updates
### ❌ Pitfall 5: Resource Deletion Protection Missing
**Problem:** Accidental resource deletion causes data loss.
**Solution:**
- Set DeletionPolicy: Snapshot for databases
- Enable DeletionProtection on production resources
- Use stack policies to prevent changes
### ❌ Pitfall 6: No Outputs Defined
**Problem:** Stack created but outputs hidden; hard to use resources.
**Solution:**
- Define all important resource IDs in Outputs
- Export outputs for cross-stack references
- Document output purposes
---
## Best Practices Summary
| Category | Best Practice |
|---|---|
| **Design** | Modular nested stacks; separate concerns |
| **Parameters** | Parameterize all environment-specific values |
| **Updates** | Use change sets; review before execution |
| **Safety** | Stack policies; termination protection; DeletionPolicy |
| **Version Control** | Git version all templates and parameters |
| **Documentation** | Clear Metadata; parameter descriptions; Outputs |
---
## Related Skills
| Skill | Purpose |
|---|---|
| `cncf-aws-iam` | IAM roles for CloudFormation |
| `cncf-aws-ec2` | EC2 resources in templates |
| `cncf-aws-rds` | Database resources in templates |
| `cncf-aws-vpc` | VPC and networking in templates |
---
## Core Workflow
1. **Assess Requirements** — Understand the use case, scale, integration needs, and existing infrastructure. **Checkpoint:** Document requirements, constraints, and success criteria.
2. **Design Architecture** — Plan component interactions, data flow, and deployment strategy using cloud-native best practices. **Checkpoint:** Verify the architecture addresses all requirements and follows CNCF conventions.
3. **Implement & Configure** — Create manifests, configurations, and deployment scripts. Include resource limits, health checks, and observability hooks. **Checkpoint:** Validate all YAML against schema and test in a staging environment.
4. **Deploy & Monitor** — Apply manifests to the cluster, verify component health, and confirm observability is working. **Checkpoint:** Confirm all pods/services are running, probes passing, and metrics/alerts configured.
---
## Constraints
### MUST DO
- Include at least one complete working YAML manifest example
- Note when content is auto-generated vs. manually verified
- Reference relevant CNCF project documentation
### MUST NOT DO
- Deploy manifests without testing in a staging environment first
- Use deprecated API versions (e.g., apps/v1beta1)
- Omit resource limits and requests in Kubernetes manifests
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!