用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/tools-only/X-Skills --skill cloudformation-generate命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
基于 SOC 职业分类
正在显示 SKILL.md
| name | cloudformation-generate |
| description | Convert Terraform to CloudFormation or generate CFN templates |
| shortcut | cfn |
| category | devops |
| difficulty | advanced |
| estimated_time | 3 minutes |
Generates AWS CloudFormation templates from scratch or helps convert Terraform configurations to CloudFormation (with limitations).
You are a CloudFormation expert. When user runs /cloudformation-generate or /cfn:
Understand requirements:
Generate CloudFormation structure:
AWSTemplateFormatVersion: '2010-09-09'
Description: [template description]
Parameters: # User inputs
Mappings: # Lookup tables (optional)
Conditions: # Conditional logic (optional)
Resources: # AWS resources (REQUIRED)
Outputs: # Return values
Apply CFN best practices:
Provide deployment guide:
# Complete CloudFormation template
# Ready to deploy with aws cloudformation create-stack
## Deployment
### CLI:
```bash
aws cloudformation create-stack \
--stack-name my-stack \
--template-body file://template.yaml \
--parameters [params]
[Step-by-step instructions]
## Example
**User:** `/cfn`
**Request:** Create VPC with public/private subnets, similar to Terraform VPC module
**Output:**
```yaml
AWSTemplateFormatVersion: '2010-09-09'
Description: 'VPC with public and private subnets across 2 AZs'
Parameters:
VPCName:
Description: Name of the VPC
Type: String
Default: MyVPC
VPCCIDR:
Description: CIDR block for VPC
Type: String
Default: 10.0.0.0/16
AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))$
PublicSubnet1CIDR:
Description: CIDR for public subnet in AZ1
Type: String
Default: 10.0.1.0/24
PublicSubnet2CIDR:
Description: CIDR for public subnet in AZ2
Type: String
Default: 10.0.2.0/24
PrivateSubnet1CIDR:
Description: CIDR for private subnet in AZ1
Type: String
Default: 10.0.11.0/24
PrivateSubnet2CIDR:
Description: CIDR for private subnet in AZ2
Type: String
Default: 10.0.12.0/24
Environment:
Description: Environment name
Type: String
Default: dev
AllowedValues:
- dev
- staging
- production
Conditions:
IsProduction: !Equals [!Ref Environment, production]
Mappings:
AZMapping:
us-east-1:
AZ1: us-east-1a
AZ2: us-east-1b
us-west-2:
AZ1: us-west-2a
AZ2: us-west-2b
Resources:
# VPC
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: !Ref VPCCIDR
EnableDnsHostnames: true
EnableDnsSupport: true
Tags:
- Key: Name
Value: !Ref VPCName
- Key: Environment
Value: !Ref Environment
# Internet Gateway
InternetGateway:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
- Key: Name
Value: !Sub '${VPCName}-igw'
AttachGateway:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId: !Ref VPC
InternetGatewayId: !Ref InternetGateway
# Public Subnets
PublicSubnet1:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock: !Ref PublicSubnet1CIDR
AvailabilityZone: !FindInMap [AZMapping, !Ref 'AWS::Region', AZ1]
MapPublicIpOnLaunch: true
Tags:
- Key: Name
Value: !Sub '${VPCName}-public-1'
- Key: Type
Value: public
PublicSubnet2:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock: !Ref PublicSubnet2CIDR
AvailabilityZone: !FindInMap [AZMapping, !Ref 'AWS::Region', AZ2]
MapPublicIpOnLaunch: true
Tags:
- Key: Name
Value: !Sub '${VPCName}-public-2'
- Key: Type
Value: public
# Private Subnets
PrivateSubnet1:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock: !Ref PrivateSubnet1CIDR
AvailabilityZone: !FindInMap [AZMapping, !Ref 'AWS::Region', AZ1]
Tags:
- Key: Name
Value: !Sub '${VPCName}-private-1'
- Key: Type
Value: private
PrivateSubnet2:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock: !Ref PrivateSubnet2CIDR
AvailabilityZone: !FindInMap [AZMapping, !Ref 'AWS::Region', AZ2]
Tags:
- Key: Name
Value: !Sub '${VPCName}-private-2'
- Key: Type
Value: private
# Elastic IPs for NAT Gateways
NatGateway1EIP:
Type: AWS::EC2::EIP
DependsOn: AttachGateway
Properties:
Domain: vpc
Tags:
- Key: Name
Value: !Sub '${VPCName}-nat-eip-1'
NatGateway2EIP:
Type: AWS::EC2::EIP
DependsOn: AttachGateway
Condition: IsProduction # Only create second NAT in production
Properties:
Domain: vpc
Tags:
- Key: Name
Value: !Sub '${VPCName}-nat-eip-2'
# NAT Gateways
NatGateway1:
Type: AWS::EC2::NatGateway
Properties:
AllocationId: !GetAtt NatGateway1EIP.AllocationId
SubnetId: !Ref PublicSubnet1
Tags:
- Key: Name
Value: !Sub '${VPCName}-nat-1'
NatGateway2:
Type: AWS::EC2::NatGateway
Condition: IsProduction
Properties:
AllocationId: !GetAtt NatGateway2EIP.AllocationId
SubnetId: !Ref PublicSubnet2
Tags:
- Key: Name
Value: !Sub '${VPCName}-nat-2'
# Public Route Table
PublicRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub '${VPCName}-public-rt'
PublicRoute:
Type: AWS::EC2::Route
DependsOn: AttachGateway
Properties:
RouteTableId: !Ref PublicRouteTable
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref InternetGateway
PublicSubnet1RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PublicSubnet1
RouteTableId: !Ref PublicRouteTable
PublicSubnet2RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PublicSubnet2
RouteTableId: !Ref PublicRouteTable
# Private Route Tables
PrivateRouteTable1:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub '${VPCName}-private-rt-1'
PrivateRoute1:
Type: AWS::EC2::Route
Properties:
RouteTableId: !Ref PrivateRouteTable1
DestinationCidrBlock: 0.0.0.0/0
NatGatewayId: !Ref NatGateway1
PrivateSubnet1RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PrivateSubnet1
RouteTableId: !Ref PrivateRouteTable1
PrivateRouteTable2:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub '${VPCName}-private-rt-2'
PrivateRoute2:
Type: AWS::EC2::Route
Properties:
RouteTableId: !Ref PrivateRouteTable2
DestinationCidrBlock: 0.0.0.0/0
NatGatewayId: !If [IsProduction, !Ref NatGateway2, !Ref NatGateway1]
PrivateSubnet2RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PrivateSubnet2
RouteTableId: !Ref PrivateRouteTable2
Outputs:
VPCID:
Description: VPC ID
Value: !Ref VPC
Export:
Name: !Sub '${AWS::StackName}-VPCID'
VPCCIDR:
Description: VPC CIDR block
Value: !GetAtt VPC.CidrBlock
PublicSubnets:
Description: Public subnet IDs (comma-separated)
Value: !Join [',', [!Ref PublicSubnet1, !Ref PublicSubnet2]]
Export:
Name: !Sub '${AWS::StackName}-PublicSubnets'
PrivateSubnets:
Description: Private subnet IDs (comma-separated)
Value: !Join [',', [!Ref PrivateSubnet1, !Ref PrivateSubnet2]]
Export:
Name: !Sub '${AWS::StackName}-PrivateSubnets'
NatGatewayIPs:
Description: NAT Gateway Elastic IPs
Value: !If
- IsProduction
- !Join [',', [!Ref NatGateway1EIP, !Ref NatGateway2EIP]]
- !Ref NatGateway1EIP
Deployment Instructions:
# 1. Validate template
aws cloudformation validate-template --template-body file://vpc-template.yaml
# 2. Create stack (development)
aws cloudformation create-stack \
--stack-name myapp-vpc-dev \
--template-body file://vpc-template.yaml \
--parameters \
ParameterKey=VPCName,ParameterValue=myapp-dev \
ParameterKey=Environment,ParameterValue=dev
# 3. Create stack (production)
aws cloudformation create-stack \
--stack-name myapp-vpc-prod \
--template-body file://vpc-template.yaml \
--parameters \
ParameterKey=VPCName,ParameterValue=myapp-prod \
ParameterKey=Environment,ParameterValue=production
# 4. Check stack status
aws cloudformation describe-stacks --stack-name myapp-vpc-dev
# 5. Get outputs
aws cloudformation describe-stacks \
--stack-name myapp-vpc-dev \
--query 'Stacks[0].Outputs'
# 6. Update stack
aws cloudformation update-stack \
--stack-name myapp-vpc-dev \
--template-body file://vpc-template.yaml \
--parameters [same as create]
# 7. Delete stack
aws cloudformation delete-stack --stack-name myapp-vpc-dev
Parameters:
Conditions:
IsProduction creates second NAT only in prod (cost savings)!If function for conditional resource referencesMappings:
AZMapping for region-specific availability zonesIntrinsic Functions:
!Ref - Reference parameters or resources!GetAtt - Get attribute from resource!Sub - String substitution!Join - Concatenate values!FindInMap - Lookup from mappingOutputs with Exports:
!ImportValue| Feature | Terraform | CloudFormation |
|---|---|---|
| Multi-cloud | Yes | AWS only |
| State management | Required | Managed by AWS |
| Syntax | HCL (readable) | YAML/JSON (verbose) |
| Modules | Excellent | Nested stacks (complex) |
| Plan preview | terraform plan | Change sets |
| Drift detection | Built-in | Built-in |
Use parameters for reusability Export outputs for cross-stack references Use conditions for environment differences Always use DependsOn for correct ordering Validate template before deploying
Terraform → CloudFormation:
# Terraform
resource "aws_s3_bucket" "assets" {
bucket = "myapp-assets"
}
# CloudFormation
Resources:
AssetsBucket:
Type: AWS::S3::Bucket
Properties:
BucketName: myapp-assets