aws-cloudformation-vpc

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

AWS CloudFormation VPC Infrastructure

AWS CloudFormation VPC基础设施

Overview

概述

Create production-ready VPC infrastructure using AWS CloudFormation templates. This skill covers VPC components (Subnets, Route Tables, NAT Gateways, Internet Gateways), template structure best practices, parameter patterns, and cross-stack references for modular, reusable infrastructure as code.
使用AWS CloudFormation模板创建可用于生产环境的VPC基础设施。本文涵盖VPC组件(Subnets、Route Tables、NAT Gateways、Internet Gateways)、模板结构最佳实践、参数模式,以及用于模块化、可重用基础设施即代码的跨栈引用。

When to Use

适用场景

Use this skill when:
  • Creating new VPCs with public and private subnets
  • Configuring route tables for internet and NAT connectivity
  • Setting up Internet Gateways and NAT Gateways
  • Implementing template Parameters with AWS-specific types
  • Creating Outputs for cross-stack references
  • Organizing templates with Mappings and Conditions
  • Designing reusable, modular CloudFormation templates
在以下场景中使用本文内容:
  • 创建包含公有子网和私有子网的新VPC
  • 配置用于互联网和NAT连通性的路由表
  • 搭建Internet Gateway和NAT Gateway
  • 实现带有AWS特定类型的模板Parameters
  • 创建用于跨栈引用的Outputs
  • 使用Mappings和Conditions组织模板
  • 设计可重用、模块化的CloudFormation模板

Quick Start

快速开始

Basic VPC with Public Subnet

带公有子网的基础VPC

yaml
AWSTemplateFormatVersion: 2010-09-09
Description: Simple VPC with public subnet

Resources:
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/16
      EnableDnsHostnames: true
      EnableDnsSupport: true
      Tags:
        - Key: Name
          Value: !Sub ${AWS::StackName}-vpc

  PublicSubnet:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: 10.0.1.0/24
      AvailabilityZone: !Select [0, !GetAZs '']
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: !Sub ${AWS::StackName}-public-subnet

  InternetGateway:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags:
        - Key: Name
          Value: !Sub ${AWS::StackName}-igw

  VPCGatewayAttachment:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId: !Ref VPC
      InternetGatewayId: !Ref InternetGateway

  PublicRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: !Sub ${AWS::StackName}-public-rt

  DefaultPublicRoute:
    Type: AWS::EC2::Route
    DependsOn: VPCGatewayAttachment
    Properties:
      RouteTableId: !Ref PublicRouteTable
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref InternetGateway

  PublicSubnetRouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnet
      RouteTableId: !Ref PublicRouteTable
yaml
AWSTemplateFormatVersion: 2010-09-09
Description: Simple VPC with public subnet

Resources:
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/16
      EnableDnsHostnames: true
      EnableDnsSupport: true
      Tags:
        - Key: Name
          Value: !Sub ${AWS::StackName}-vpc

  PublicSubnet:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: 10.0.1.0/24
      AvailabilityZone: !Select [0, !GetAZs '']
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: !Sub ${AWS::StackName}-public-subnet

  InternetGateway:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags:
        - Key: Name
          Value: !Sub ${AWS::StackName}-igw

  VPCGatewayAttachment:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId: !Ref VPC
      InternetGatewayId: !Ref InternetGateway

  PublicRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: !Sub ${AWS::StackName}-public-rt

  DefaultPublicRoute:
    Type: AWS::EC2::Route
    DependsOn: VPCGatewayAttachment
    Properties:
      RouteTableId: !Ref PublicRouteTable
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref InternetGateway

  PublicSubnetRouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnet
      RouteTableId: !Ref PublicRouteTable

VPC with Public and Private Subnets

带公有和私有子网的VPC

yaml
AWSTemplateFormatVersion: 2010-09-09
Description: VPC with public and private subnets across multiple AZs

Parameters:
  EnvironmentName:
    Type: String
    Default: production
    Description: Environment name for resource tagging

  VpcCidr:
    Type: String
    Default: 10.0.0.0/16
    Description: CIDR block for the VPC

Resources:
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: !Ref VpcCidr
      EnableDnsHostnames: true
      EnableDnsSupport: true
      Tags:
        - Key: Environment
          Value: !Ref EnvironmentName
        - Key: Name
          Value: !Sub ${AWS::StackName}-vpc

  InternetGateway:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags:
        - Key: Environment
          Value: !Ref EnvironmentName
        - Key: Name
          Value: !Sub ${AWS::StackName}-igw

  VPCGatewayAttachment:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId: !Ref VPC
      InternetGatewayId: !Ref InternetGateway

  # Public Subnet 1
  PublicSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: 10.0.1.0/24
      AvailabilityZone: !Select [0, !GetAZs '']
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Environment
          Value: !Ref EnvironmentName
        - Key: SubnetType
          Value: Public
        - Key: Name
          Value: !Sub ${AWS::StackName}-public-1

  PublicRouteTable1:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Environment
          Value: !Ref EnvironmentName
        - Key: Name
          Value: !Sub ${AWS::StackName}-public-rt-1

  DefaultPublicRoute1:
    Type: AWS::EC2::Route
    DependsOn: VPCGatewayAttachment
    Properties:
      RouteTableId: !Ref PublicRouteTable1
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref InternetGateway

  PublicSubnetRouteTableAssociation1:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnet1
      RouteTableId: !Ref PublicRouteTable1

  # Private Subnet 1
  PrivateSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: 10.0.10.0/24
      AvailabilityZone: !Select [0, !GetAZs '']
      Tags:
        - Key: Environment
          Value: !Ref EnvironmentName
        - Key: SubnetType
          Value: Private
        - Key: Name
          Value: !Sub ${AWS::StackName}-private-1

  PrivateRouteTable1:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Environment
          Value: !Ref EnvironmentName
        - Key: Name
          Value: !Sub ${AWS::StackName}-private-rt-1

  PrivateSubnetRouteTableAssociation1:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PrivateSubnet1
      RouteTableId: !Ref PrivateRouteTable1

Outputs:
  VpcId:
    Description: VPC ID
    Value: !Ref VPC
    Export:
      Name: !Sub ${AWS::StackName}-VpcId

  PublicSubnet1Id:
    Description: Public Subnet 1 ID
    Value: !Ref PublicSubnet1
    Export:
      Name: !Sub ${AWS::StackName}-PublicSubnet1Id

  PrivateSubnet1Id:
    Description: Private Subnet 1 ID
    Value: !Ref PrivateSubnet1
    Export:
      Name: !Sub ${AWS::StackName}-PrivateSubnet1Id
yaml
AWSTemplateFormatVersion: 2010-09-09
Description: VPC with public and private subnets across multiple AZs

Parameters:
  EnvironmentName:
    Type: String
    Default: production
    Description: Environment name for resource tagging

  VpcCidr:
    Type: String
    Default: 10.0.0.0/16
    Description: CIDR block for the VPC

Resources:
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: !Ref VpcCidr
      EnableDnsHostnames: true
      EnableDnsSupport: true
      Tags:
        - Key: Environment
          Value: !Ref EnvironmentName
        - Key: Name
          Value: !Sub ${AWS::StackName}-vpc

  InternetGateway:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags:
        - Key: Environment
          Value: !Ref EnvironmentName
        - Key: Name
          Value: !Sub ${AWS::StackName}-igw

  VPCGatewayAttachment:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId: !Ref VPC
      InternetGatewayId: !Ref InternetGateway

  # Public Subnet 1
  PublicSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: 10.0.1.0/24
      AvailabilityZone: !Select [0, !GetAZs '']
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Environment
          Value: !Ref EnvironmentName
        - Key: SubnetType
          Value: Public
        - Key: Name
          Value: !Sub ${AWS::StackName}-public-1

  PublicRouteTable1:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Environment
          Value: !Ref EnvironmentName
        - Key: Name
          Value: !Sub ${AWS::StackName}-public-rt-1

  DefaultPublicRoute1:
    Type: AWS::EC2::Route
    DependsOn: VPCGatewayAttachment
    Properties:
      RouteTableId: !Ref PublicRouteTable1
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref InternetGateway

  PublicSubnetRouteTableAssociation1:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnet1
      RouteTableId: !Ref PublicRouteTable1

  # Private Subnet 1
  PrivateSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: 10.0.10.0/24
      AvailabilityZone: !Select [0, !GetAZs '']
      Tags:
        - Key: Environment
          Value: !Ref EnvironmentName
        - Key: SubnetType
          Value: Private
        - Key: Name
          Value: !Sub ${AWS::StackName}-private-1

  PrivateRouteTable1:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Environment
          Value: !Ref EnvironmentName
        - Key: Name
          Value: !Sub ${AWS::StackName}-private-rt-1

  PrivateSubnetRouteTableAssociation1:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PrivateSubnet1
      RouteTableId: !Ref PrivateRouteTable1

Outputs:
  VpcId:
    Description: VPC ID
    Value: !Ref VPC
    Export:
      Name: !Sub ${AWS::StackName}-VpcId

  PublicSubnet1Id:
    Description: Public Subnet 1 ID
    Value: !Ref PublicSubnet1
    Export:
      Name: !Sub ${AWS::StackName}-PublicSubnet1Id

  PrivateSubnet1Id:
    Description: Private Subnet 1 ID
    Value: !Ref PrivateSubnet1
    Export:
      Name: !Sub ${AWS::StackName}-PrivateSubnet1Id

Template Structure

模板结构

Template Sections Overview

模板章节概述

AWS CloudFormation templates are JSON or YAML files with specific sections. Each section serves a purpose in defining your infrastructure.
yaml
AWSTemplateFormatVersion: 2010-09-09  # Required - template version
Description: Optional description string  # Optional description
AWS CloudFormation模板是包含特定章节的JSON或YAML文件,每个章节在定义基础设施时都有其特定用途。
yaml
AWSTemplateFormatVersion: 2010-09-09  # Required - template version
Description: Optional description string  # Optional description

Section order matters for readability but CloudFormation accepts any order

Section order matters for readability but CloudFormation accepts any order

Mappings: {} # Static configuration tables Metadata: {} # Additional information about resources Parameters: {} # Input values for customization Rules: {} # Parameter validation rules Conditions: {} # Conditional resource creation Transform: {} # Macro processing (e.g., AWS::Serverless) Resources: {} # AWS resources to create (REQUIRED) Outputs: {} # Return values after stack creation
undefined
Mappings: {} # Static configuration tables Metadata: {} # Additional information about resources Parameters: {} # Input values for customization Rules: {} # Parameter validation rules Conditions: {} # Conditional resource creation Transform: {} # Macro processing (e.g., AWS::Serverless) Resources: {} # AWS resources to create (REQUIRED) Outputs: {} # Return values after stack creation
undefined

Format Version

格式版本

The
AWSTemplateFormatVersion
identifies the template version. Current version is
2010-09-09
.
yaml
AWSTemplateFormatVersion: 2010-09-09
Description: My CloudFormation Template
AWSTemplateFormatVersion
用于标识模板版本,当前版本为
2010-09-09
yaml
AWSTemplateFormatVersion: 2010-09-09
Description: My CloudFormation Template

Description

描述

Add a description to document the template's purpose. Must appear after the format version.
yaml
AWSTemplateFormatVersion: 2010-09-09
Description: >
  This template creates a VPC with public and private subnets
  for hosting web applications. It includes:
  - Internet Gateway for public access
  - NAT Gateway for private subnet outbound access
  - Security groups for web and database tiers
添加描述来记录模板的用途,必须出现在格式版本之后。
yaml
AWSTemplateFormatVersion: 2010-09-09
Description: >
  This template creates a VPC with public and private subnets
  for hosting web applications. It includes:
  - Internet Gateway for public access
  - NAT Gateway for private subnet outbound access
  - Security groups for web and database tiers

Metadata

元数据

Use
Metadata
for additional information about resources or parameters.
yaml
Metadata:
  AWS::CloudFormation::Interface:
    ParameterGroups:
      - Label:
          default: Network Configuration
        Parameters:
          - VpcCidr
          - PublicSubnetCidr
          - PrivateSubnetCidr
      - Label:
          default: Tags
        Parameters:
          - EnvironmentName
          - ProjectName
    ParameterLabels:
      VpcCidr:
        default: VPC CIDR Block
      EnvironmentName:
        default: Environment Name
使用
Metadata
添加关于资源或参数的额外信息。
yaml
Metadata:
  AWS::CloudFormation::Interface:
    ParameterGroups:
      - Label:
          default: Network Configuration
        Parameters:
          - VpcCidr
          - PublicSubnetCidr
          - PrivateSubnetCidr
      - Label:
          default: Tags
        Parameters:
          - EnvironmentName
          - ProjectName
    ParameterLabels:
      VpcCidr:
        default: VPC CIDR Block
      EnvironmentName:
        default: Environment Name

Resources Section

资源章节

The
Resources
section is the only required section. It defines AWS resources to provision.
yaml
Resources:
  MyVPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/16
      EnableDnsHostnames: true
      EnableDnsSupport: true
      Tags:
        - Key: Name
          Value: !Sub ${AWS::StackName}-vpc
Resources
是唯一必填的章节,用于定义要创建的AWS资源。
yaml
Resources:
  MyVPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/16
      EnableDnsHostnames: true
      EnableDnsSupport: true
      Tags:
        - Key: Name
          Value: !Sub ${AWS::StackName}-vpc

Parameters

参数

Parameter Types

参数类型

Use AWS-specific parameter types for validation and easier selection in the console.
yaml
Parameters:
  VpcId:
    Type: AWS::EC2::VPC::Id
    Description: Select an existing VPC

  SubnetId:
    Type: AWS::EC2::Subnet::Id
    Description: Select a subnet

  SecurityGroupIds:
    Type: List<AWS::EC2::SecurityGroup::Id>
    Description: Select existing security groups

  InstanceType:
    Type: AWS::EC2::InstanceType
    Description: EC2 instance type
    Default: t3.micro
    AllowedValues:
      - t3.micro
      - t3.small
      - t3.medium
      - t3.large

  AmiId:
    Type: AWS::EC2::Image::Id
    Description: Select an AMI

  KeyName:
    Type: AWS::EC2::KeyPair::KeyName
    Description: Select an existing key pair
使用AWS特定的参数类型进行验证,并方便在控制台中选择。
yaml
Parameters:
  VpcId:
    Type: AWS::EC2::VPC::Id
    Description: Select an existing VPC

  SubnetId:
    Type: AWS::EC2::Subnet::Id
    Description: Select a subnet

  SecurityGroupIds:
    Type: List<AWS::EC2::SecurityGroup::Id>
    Description: Select existing security groups

  InstanceType:
    Type: AWS::EC2::InstanceType
    Description: EC2 instance type
    Default: t3.micro
    AllowedValues:
      - t3.micro
      - t3.small
      - t3.medium
      - t3.large

  AmiId:
    Type: AWS::EC2::Image::Id
    Description: Select an AMI

  KeyName:
    Type: AWS::EC2::KeyPair::KeyName
    Description: Select an existing key pair

Parameter Constraints

参数约束

Add constraints to validate parameter values.
yaml
Parameters:
  VpcCidr:
    Type: String
    Description: CIDR block for the VPC
    Default: 10.0.0.0/16
    AllowedPattern: ^([0-9]{1,3}\.){3}[0-9]{1,3}/[0-9]{1,2}$
    ConstraintDescription: Must be a valid CIDR block (x.x.x.x/x)

  InstanceCount:
    Type: Number
    Description: Number of instances to launch
    Default: 1
    MinValue: 1
    MaxValue: 10

  Environment:
    Type: String
    Description: Deployment environment
    Default: development
    AllowedValues:
      - development
      - staging
      - production
    ConstraintDescription: Must be development, staging, or production
添加约束来验证参数值。
yaml
Parameters:
  VpcCidr:
    Type: String
    Description: CIDR block for the VPC
    Default: 10.0.0.0/16
    AllowedPattern: ^([0-9]{1,3}\.){3}[0-9]{1,3}/[0-9]{1,2}$
    ConstraintDescription: Must be a valid CIDR block (x.x.x.x/x)

  InstanceCount:
    Type: Number
    Description: Number of instances to launch
    Default: 1
    MinValue: 1
    MaxValue: 10

  Environment:
    Type: String
    Description: Deployment environment
    Default: development
    AllowedValues:
      - development
      - staging
      - production
    ConstraintDescription: Must be development, staging, or production

SSM Parameter Types

SSM参数类型

Reference Systems Manager parameters for dynamic values.
yaml
Parameters:
  LatestAmiId:
    Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
    Description: Latest AMI ID from SSM
    Default: /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2
引用Systems Manager参数来获取动态值。
yaml
Parameters:
  LatestAmiId:
    Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
    Description: Latest AMI ID from SSM
    Default: /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2

Mappings

映射

Use
Mappings
for static configuration data based on regions or other factors.
yaml
Mappings:
  RegionMap:
    us-east-1:
      HVM64: ami-0ff8a95407f89df2f
      HVMG2: ami-0a0c776d80e2a1f3c
    us-west-2:
      HVM64: ami-0a0c776d80e2a1f3c
      HVMG2: ami-0a0c776d80e2a1f3c
    eu-west-1:
      HVM64: ami-0ff8a95407f89df2f
      HVMG2: ami-0a0c776d80e2a1f3c

  EnvironmentConfig:
    development:
      InstanceType: t3.micro
      MinInstances: 1
      MaxInstances: 2
    staging:
      InstanceType: t3.small
      MinInstances: 1
      MaxInstances: 3
    production:
      InstanceType: t3.medium
      MinInstances: 2
      MaxInstances: 10

Resources:
  Instance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !FindInMap [RegionMap, !Ref AWS::Region, HVM64]
      InstanceType: !FindInMap [EnvironmentConfig, !Ref Environment, InstanceType]
使用
Mappings
存储基于区域或其他因素的静态配置数据。
yaml
Mappings:
  RegionMap:
    us-east-1:
      HVM64: ami-0ff8a95407f89df2f
      HVMG2: ami-0a0c776d80e2a1f3c
    us-west-2:
      HVM64: ami-0a0c776d80e2a1f3c
      HVMG2: ami-0a0c776d80e2a1f3c
    eu-west-1:
      HVM64: ami-0ff8a95407f89df2f
      HVMG2: ami-0a0c776d80e2a1f3c

  EnvironmentConfig:
    development:
      InstanceType: t3.micro
      MinInstances: 1
      MaxInstances: 2
    staging:
      InstanceType: t3.small
      MinInstances: 1
      MaxInstances: 3
    production:
      InstanceType: t3.medium
      MinInstances: 2
      MaxInstances: 10

Resources:
  Instance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !FindInMap [RegionMap, !Ref AWS::Region, HVM64]
      InstanceType: !FindInMap [EnvironmentConfig, !Ref Environment, InstanceType]

Conditions

条件

Use
Conditions
to conditionally create resources based on parameters.
yaml
Parameters:
  DeployNatGateway:
    Type: String
    Default: true
    AllowedValues:
      - true
      - false

  Environment:
    Type: String
    Default: development
    AllowedValues:
      - development
      - staging
      - production

Conditions:
  ShouldDeployNat: !Equals [!Ref DeployNatGateway, true]
  IsProduction: !Equals [!Ref Environment, production]

Resources:
  NatGateway:
    Type: AWS::EC2::NatGateway
    Condition: ShouldDeployNat
    Properties:
      AllocationId: !If
        - ShouldDeployNat
        - !GetAtt EIP.AllocationId
        - !Ref AWS::NoValue
      SubnetId: !Ref PublicSubnet

  ProductionOnlyResource:
    Type: AWS::EC2::VPCEndpoint
    Condition: IsProduction
    Properties:
      ServiceName: !Sub com.amazonaws.${AWS::Region}.s3
      VpcId: !Ref VPC
使用
Conditions
根据参数值有条件地创建资源。
yaml
Parameters:
  DeployNatGateway:
    Type: String
    Default: true
    AllowedValues:
      - true
      - false

  Environment:
    Type: String
    Default: development
    AllowedValues:
      - development
      - staging
      - production

Conditions:
  ShouldDeployNat: !Equals [!Ref DeployNatGateway, true]
  IsProduction: !Equals [!Ref Environment, production]

Resources:
  NatGateway:
    Type: AWS::EC2::NatGateway
    Condition: ShouldDeployNat
    Properties:
      AllocationId: !If
        - ShouldDeployNat
        - !GetAtt EIP.AllocationId
        - !Ref AWS::NoValue
      SubnetId: !Ref PublicSubnet

  ProductionOnlyResource:
    Type: AWS::EC2::VPCEndpoint
    Condition: IsProduction
    Properties:
      ServiceName: !Sub com.amazonaws.${AWS::Region}.s3
      VpcId: !Ref VPC

Transform

转换

Use
Transform
for macros like AWS::Serverless for SAM templates.
yaml
AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::Serverless-2016-10-31
Description: SAM template for serverless application

Resources:
  MyFunction:
    Type: AWS::Serverless::Function
    Properties:
      Handler: index.handler
      Runtime: nodejs18.x
      CodeUri: function/
      Events:
        ApiEvent:
          Type: Api
          Properties:
            Path: /{proxy+}
            Method: ANY
使用
Transform
来调用宏,比如用于SAM模板的AWS::Serverless。
yaml
AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::Serverless-2016-10-31
Description: SAM template for serverless application

Resources:
  MyFunction:
    Type: AWS::Serverless::Function
    Properties:
      Handler: index.handler
      Runtime: nodejs18.x
      CodeUri: function/
      Events:
        ApiEvent:
          Type: Api
          Properties:
            Path: /{proxy+}
            Method: ANY

Outputs and Cross-Stack References

输出与跨栈引用

Basic Outputs

基础输出

yaml
Outputs:
  VpcId:
    Description: VPC ID
    Value: !Ref VPC

  PublicSubnetId:
    Description: Public Subnet ID
    Value: !Ref PublicSubnet

  VpcCidr:
    Description: VPC CIDR Block
    Value: !GetAtt VPC.CidrBlock
yaml
Outputs:
  VpcId:
    Description: VPC ID
    Value: !Ref VPC

  PublicSubnetId:
    Description: Public Subnet ID
    Value: !Ref PublicSubnet

  VpcCidr:
    Description: VPC CIDR Block
    Value: !GetAtt VPC.CidrBlock

Exporting Values for Cross-Stack References

导出值用于跨栈引用

Export values so other stacks can import them.
yaml
Outputs:
  VpcId:
    Description: VPC ID for other stacks
    Value: !Ref VPC
    Export:
      Name: !Sub ${AWS::StackName}-VpcId

  PublicSubnetIds:
    Description: Comma-separated public subnet IDs
    Value: !Join [",", [!Ref PublicSubnet1, !Ref PublicSubnet2]]
    Export:
      Name: !Sub ${AWS::StackName}-PublicSubnetIds

  PrivateSubnetIds:
    Description: Comma-separated private subnet IDs
    Value: !Join [",", [!Ref PrivateSubnet1, !Ref PrivateSubnet2]]
    Export:
      Name: !Sub ${AWS::StackName}-PrivateSubnetIds
导出值以便其他栈可以导入使用。
yaml
Outputs:
  VpcId:
    Description: VPC ID for other stacks
    Value: !Ref VPC
    Export:
      Name: !Sub ${AWS::StackName}-VpcId

  PublicSubnetIds:
    Description: Comma-separated public subnet IDs
    Value: !Join [",", [!Ref PublicSubnet1, !Ref PublicSubnet2]]
    Export:
      Name: !Sub ${AWS::StackName}-PublicSubnetIds

  PrivateSubnetIds:
    Description: Comma-separated private subnet IDs
    Value: !Join [",", [!Ref PrivateSubnet1, !Ref PrivateSubnet2]]
    Export:
      Name: !Sub ${AWS::StackName}-PrivateSubnetIds

Importing Values in Another Stack

在另一个栈中导入值

yaml
Parameters:
  VpcId:
    Type: AWS::EC2::VPC::Id
    Description: VPC ID from network stack
    # User selects from exported values in console

  # Or use Fn::ImportValue for programmatic access
Resources:
  SecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      VpcId: !ImportValue
        Fn::Sub: ${NetworkStackName}-VpcId
      GroupDescription: Security group for application
yaml
Parameters:
  VpcId:
    Type: AWS::EC2::VPC::Id
    Description: VPC ID from network stack
    # User selects from exported values in console

  # Or use Fn::ImportValue for programmatic access
Resources:
  SecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      VpcId: !ImportValue
        Fn::Sub: ${NetworkStackName}-VpcId
      GroupDescription: Security group for application

Cross-Stack Reference Pattern

跨栈引用模式

Create a dedicated network stack that exports values:
yaml
undefined
创建一个专用的网络栈来导出值:
yaml
undefined

network-stack.yaml

network-stack.yaml

AWSTemplateFormatVersion: 2010-09-09 Description: Network infrastructure stack
Resources: VPC: Type: AWS::EC2::VPC Properties: CidrBlock: 10.0.0.0/16 Tags: - Key: Name Value: !Sub ${AWS::StackName}-vpc
PublicSubnets: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC CidrBlock: 10.0.1.0/24 AvailabilityZone: !Select [0, !GetAZs ''] MapPublicIpOnLaunch: true
Outputs: VpcId: Value: !Ref VPC Export: Name: !Sub ${AWS::StackName}-VpcId
PublicSubnetIds: Value: !Ref PublicSubnets Export: Name: !Sub ${AWS::StackName}-PublicSubnetIds

Application stack imports these values:

```yaml
AWSTemplateFormatVersion: 2010-09-09 Description: Network infrastructure stack
Resources: VPC: Type: AWS::EC2::VPC Properties: CidrBlock: 10.0.0.0/16 Tags: - Key: Name Value: !Sub ${AWS::StackName}-vpc
PublicSubnets: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC CidrBlock: 10.0.1.0/24 AvailabilityZone: !Select [0, !GetAZs ''] MapPublicIpOnLaunch: true
Outputs: VpcId: Value: !Ref VPC Export: Name: !Sub ${AWS::StackName}-VpcId
PublicSubnetIds: Value: !Ref PublicSubnets Export: Name: !Sub ${AWS::StackName}-PublicSubnetIds

应用栈导入这些值:

```yaml

application-stack.yaml

application-stack.yaml

AWSTemplateFormatVersion: 2010-09-09 Description: Application stack that imports from network
Parameters: NetworkStackName: Type: String Description: Name of the network stack Default: network-stack
Resources: Instance: Type: AWS::EC2::Instance Properties: SubnetId: !ImportValue Fn::Sub: ${NetworkStackName}-PublicSubnetIds InstanceType: t3.micro
undefined
AWSTemplateFormatVersion: 2010-09-09 Description: Application stack that imports from network
Parameters: NetworkStackName: Type: String Description: Name of the network stack Default: network-stack
Resources: Instance: Type: AWS::EC2::Instance Properties: SubnetId: !ImportValue Fn::Sub: ${NetworkStackName}-PublicSubnetIds InstanceType: t3.micro
undefined

VPC Components

VPC组件

VPC with All Components

包含所有组件的VPC

yaml
AWSTemplateFormatVersion: 2010-09-09
Description: Complete VPC with public/private subnets, NAT, and IGW

Parameters:
  EnvironmentName:
    Type: String
    Default: production

Resources:
  # VPC
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/16
      EnableDnsHostnames: true
      EnableDnsSupport: true
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-vpc
        - Key: Environment
          Value: !Ref EnvironmentName

  # Internet Gateway
  InternetGateway:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-igw
        - Key: Environment
          Value: !Ref EnvironmentName

  InternetGatewayAttachment:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId: !Ref VPC
      InternetGatewayId: !Ref InternetGateway

  # NAT Gateway (with EIP)
  NatGatewayEIP:
    Type: AWS::EC2::EIP
    DependsOn: InternetGatewayAttachment
    Properties:
      Domain: vpc
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-nat-eip

  NatGateway:
    Type: AWS::EC2::NatGateway
    Properties:
      AllocationId: !GetAtt NatGatewayEIP.AllocationId
      SubnetId: !Ref PublicSubnet1
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-nat-gw
        - Key: Environment
          Value: !Ref EnvironmentName

  # Public Subnets
  PublicSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: 10.0.1.0/24
      AvailabilityZone: !Select [0, !GetAZs '']
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-public-1
        - Key: SubnetType
          Value: Public

  PublicSubnet2:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: 10.0.2.0/24
      AvailabilityZone: !Select [1, !GetAZs '']
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-public-2
        - Key: SubnetType
          Value: Public

  # Private Subnets
  PrivateSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: 10.0.10.0/24
      AvailabilityZone: !Select [0, !GetAZs '']
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-private-1
        - Key: SubnetType
          Value: Private

  PrivateSubnet2:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: 10.0.11.0/24
      AvailabilityZone: !Select [1, !GetAZs '']
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-private-2
        - Key: SubnetType
          Value: Private

  # Public Route Table
  PublicRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-public-rt

  DefaultPublicRoute:
    Type: AWS::EC2::Route
    DependsOn: InternetGatewayAttachment
    Properties:
      RouteTableId: !Ref PublicRouteTable
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref InternetGateway

  PublicSubnetRouteTableAssociation1:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnet1
      RouteTableId: !Ref PublicRouteTable

  PublicSubnetRouteTableAssociation2:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnet2
      RouteTableId: !Ref PublicRouteTable

  # Private Route Table (with NAT)
  PrivateRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-private-rt

  DefaultPrivateRoute:
    Type: AWS::EC2::Route
    Properties:
      RouteTableId: !Ref PrivateRouteTable
      DestinationCidrBlock: 0.0.0.0/0
      NatGatewayId: !Ref NatGateway

  PrivateSubnetRouteTableAssociation1:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PrivateSubnet1
      RouteTableId: !Ref PrivateRouteTable

  PrivateSubnetRouteTableAssociation2:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PrivateSubnet2
      RouteTableId: !Ref PrivateRouteTable

Outputs:
  VpcId:
    Value: !Ref VPC
    Export:
      Name: !Sub ${EnvironmentName}-VpcId

  InternetGatewayId:
    Value: !Ref InternetGateway
    Export:
      Name: !Sub ${EnvironmentName}-InternetGatewayId

  PublicSubnetIds:
    Value: !Join [",", [!Ref PublicSubnet1, !Ref PublicSubnet2]]
    Export:
      Name: !Sub ${EnvironmentName}-PublicSubnetIds

  PrivateSubnetIds:
    Value: !Join [",", [!Ref PrivateSubnet1, !Ref PrivateSubnet2]]
    Export:
      Name: !Sub ${EnvironmentName}-PrivateSubnetIds

  NatGatewayId:
    Value: !Ref NatGateway
    Export:
      Name: !Sub ${EnvironmentName}-NatGatewayId
yaml
AWSTemplateFormatVersion: 2010-09-09
Description: Complete VPC with public/private subnets, NAT, and IGW

Parameters:
  EnvironmentName:
    Type: String
    Default: production

Resources:
  # VPC
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/16
      EnableDnsHostnames: true
      EnableDnsSupport: true
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-vpc
        - Key: Environment
          Value: !Ref EnvironmentName

  # Internet Gateway
  InternetGateway:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-igw
        - Key: Environment
          Value: !Ref EnvironmentName

  InternetGatewayAttachment:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId: !Ref VPC
      InternetGatewayId: !Ref InternetGateway

  # NAT Gateway (with EIP)
  NatGatewayEIP:
    Type: AWS::EC2::EIP
    DependsOn: InternetGatewayAttachment
    Properties:
      Domain: vpc
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-nat-eip

  NatGateway:
    Type: AWS::EC2::NatGateway
    Properties:
      AllocationId: !GetAtt NatGatewayEIP.AllocationId
      SubnetId: !Ref PublicSubnet1
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-nat-gw
        - Key: Environment
          Value: !Ref EnvironmentName

  # Public Subnets
  PublicSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: 10.0.1.0/24
      AvailabilityZone: !Select [0, !GetAZs '']
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-public-1
        - Key: SubnetType
          Value: Public

  PublicSubnet2:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: 10.0.2.0/24
      AvailabilityZone: !Select [1, !GetAZs '']
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-public-2
        - Key: SubnetType
          Value: Public

  # Private Subnets
  PrivateSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: 10.0.10.0/24
      AvailabilityZone: !Select [0, !GetAZs '']
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-private-1
        - Key: SubnetType
          Value: Private

  PrivateSubnet2:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: 10.0.11.0/24
      AvailabilityZone: !Select [1, !GetAZs '']
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-private-2
        - Key: SubnetType
          Value: Private

  # Public Route Table
  PublicRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-public-rt

  DefaultPublicRoute:
    Type: AWS::EC2::Route
    DependsOn: InternetGatewayAttachment
    Properties:
      RouteTableId: !Ref PublicRouteTable
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref InternetGateway

  PublicSubnetRouteTableAssociation1:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnet1
      RouteTableId: !Ref PublicRouteTable

  PublicSubnetRouteTableAssociation2:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnet2
      RouteTableId: !Ref PublicRouteTable

  # Private Route Table (with NAT)
  PrivateRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-private-rt

  DefaultPrivateRoute:
    Type: AWS::EC2::Route
    Properties:
      RouteTableId: !Ref PrivateRouteTable
      DestinationCidrBlock: 0.0.0.0/0
      NatGatewayId: !Ref NatGateway

  PrivateSubnetRouteTableAssociation1:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PrivateSubnet1
      RouteTableId: !Ref PrivateRouteTable

  PrivateSubnetRouteTableAssociation2:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PrivateSubnet2
      RouteTableId: !Ref PrivateRouteTable

Outputs:
  VpcId:
    Value: !Ref VPC
    Export:
      Name: !Sub ${EnvironmentName}-VpcId

  InternetGatewayId:
    Value: !Ref InternetGateway
    Export:
      Name: !Sub ${EnvironmentName}-InternetGatewayId

  PublicSubnetIds:
    Value: !Join [",", [!Ref PublicSubnet1, !Ref PublicSubnet2]]
    Export:
      Name: !Sub ${EnvironmentName}-PublicSubnetIds

  PrivateSubnetIds:
    Value: !Join [",", [!Ref PrivateSubnet1, !Ref PrivateSubnet2]]
    Export:
      Name: !Sub ${EnvironmentName}-PrivateSubnetIds

  NatGatewayId:
    Value: !Ref NatGateway
    Export:
      Name: !Sub ${EnvironmentName}-NatGatewayId

Best Practices

最佳实践

Use AWS-Specific Parameter Types

使用AWS特定的参数类型

Always use AWS-specific parameter types for validation and easier selection.
yaml
Parameters:
  VpcId:
    Type: AWS::EC2::VPC::Id
    Description: Select a VPC

  SubnetIds:
    Type: List<AWS::EC2::Subnet::Id>
    Description: Select subnets

  SecurityGroupIds:
    Type: List<AWS::EC2::SecurityGroup::Id>
    Description: Select security groups
始终使用AWS特定的参数类型进行验证,并方便在控制台中选择。
yaml
Parameters:
  VpcId:
    Type: AWS::EC2::VPC::Id
    Description: Select a VPC

  SubnetIds:
    Type: List<AWS::EC2::Subnet::Id>
    Description: Select subnets

  SecurityGroupIds:
    Type: List<AWS::EC2::SecurityGroup::Id>
    Description: Select security groups

Organize by Lifecycle

按生命周期组织

Separate resources that change at different rates into different stacks.
yaml
undefined
将不同变更频率的资源拆分到不同的栈中。
yaml
undefined

Network stack - rarely changes

Network stack - rarely changes

AWSTemplateFormatVersion: 2010-09-09 Description: Network infrastructure (VPC, subnets, routes) Resources: VPC: AWS::EC2::VPC Subnets: AWS::EC2::Subnet RouteTables: AWS::EC2::RouteTable
AWSTemplateFormatVersion: 2010-09-09 Description: Network infrastructure (VPC, subnets, routes) Resources: VPC: AWS::EC2::VPC Subnets: AWS::EC2::Subnet RouteTables: AWS::EC2::RouteTable

Application stack - changes frequently

Application stack - changes frequently

AWSTemplateFormatVersion: 2010-09-09 Description: Application resources Parameters: NetworkStackName: Type: String Resources: Instances: AWS::EC2::Instance
undefined
AWSTemplateFormatVersion: 2010-09-09 Description: Application resources Parameters: NetworkStackName: Type: String Resources: Instances: AWS::EC2::Instance
undefined

Use Meaningful Names

使用有意义的名称

Use
AWS::StackName
and parameters for consistent naming.
yaml
Resources:
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      Tags:
        - Key: Name
          Value: !Sub ${AWS::StackName}-vpc
        - Key: Environment
          Value: !Ref EnvironmentName
使用
AWS::StackName
和参数来保持命名一致性。
yaml
Resources:
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      Tags:
        - Key: Name
          Value: !Sub ${AWS::StackName}-vpc
        - Key: Environment
          Value: !Ref EnvironmentName

Use Pseudo Parameters

使用伪参数

Use pseudo parameters for region-agnostic templates.
yaml
Resources:
  S3Bucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Sub ${AWS::StackName}-${AWS::AccountId}-${AWS::Region}

  LambdaFunction:
    Type: AWS::Lambda::Function
    Properties:
      Runtime: nodejs18.x
      Handler: index.handler
      Role: !GetAtt LambdaExecutionRole.Arn
使用伪参数来创建与区域无关的模板。
yaml
Resources:
  S3Bucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Sub ${AWS::StackName}-${AWS::AccountId}-${AWS::Region}

  LambdaFunction:
    Type: AWS::Lambda::Function
    Properties:
      Runtime: nodejs18.x
      Handler: index.handler
      Role: !GetAtt LambdaExecutionRole.Arn

Validate Before Deployment

部署前验证

bash
undefined
bash
undefined

Validate template

Validate template

aws cloudformation validate-template --template-body file://template.yaml
aws cloudformation validate-template --template-body file://template.yaml

Check for syntax errors

Check for syntax errors

aws cloudformation validate-template
--template-body file://template.yaml
--query 'Description'
aws cloudformation validate-template
--template-body file://template.yaml
--query 'Description'

Use cfn-lint for advanced validation

Use cfn-lint for advanced validation

pip install cfn-lint cfn-lint template.yaml
undefined
pip install cfn-lint cfn-lint template.yaml
undefined

Stack Policies

栈策略

Stack Policies prevent unintentional updates to critical resources. Use them to protect production infrastructure.
json
{
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "Update:*",
      "Principal": "*",
      "Resource": "*"
    },
    {
      "Effect": "Deny",
      "Action": ["Update:Replace", "Update:Delete"],
      "Principal": "*",
      "Resource": "LogicalId=ProductionDatabase"
    },
    {
      "Effect": "Deny",
      "Action": "Update:Replace",
      "Principal": "*",
      "Resource": "LogicalId=VPC"
    }
  ]
}
Apply the stack policy:
bash
aws cloudformation set-stack-policy \
  --stack-name my-production-stack \
  --stack-policy-body file://stack-policy.json
Common Stack Policy Use Cases:
  • Protect database resources: Prevent accidental replacement of RDS instances
  • Protect VPC infrastructure: Prevent changes that could disrupt connectivity
  • Protect IAM roles: Prevent modifications that could break authorization
栈策略可防止对关键资源进行意外更新,用于保护生产环境基础设施。
json
{
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "Update:*",
      "Principal": "*",
      "Resource": "*"
    },
    {
      "Effect": "Deny",
      "Action": ["Update:Replace", "Update:Delete"],
      "Principal": "*",
      "Resource": "LogicalId=ProductionDatabase"
    },
    {
      "Effect": "Deny",
      "Action": "Update:Replace",
      "Principal": "*",
      "Resource": "LogicalId=VPC"
    }
  ]
}
应用栈策略:
bash
aws cloudformation set-stack-policy \
  --stack-name my-production-stack \
  --stack-policy-body file://stack-policy.json
常见栈策略使用场景:
  • 保护数据库资源:防止意外替换RDS实例
  • 保护VPC基础设施:防止可能中断连通性的变更
  • 保护IAM角色:防止可能破坏授权的修改

Termination Protection

终止保护

Enable termination protection to prevent accidental stack deletion. This is critical for production environments.
Enable via AWS Console:
  1. Go to CloudFormation > Stacks
  2. Select your stack
  3. Click "Stack actions" > "Enable termination protection"
Enable via AWS CLI:
bash
undefined
启用终止保护可防止意外删除栈,这对生产环境至关重要。
通过AWS控制台启用:
  1. 进入CloudFormation > 栈
  2. 选择你的栈
  3. 点击“栈操作” > “启用终止保护”
通过AWS CLI启用:
bash
undefined

Enable termination protection

Enable termination protection

aws cloudformation update-termination-protection
--stack-name my-production-stack
--enable-termination-protection
aws cloudformation update-termination-protection
--stack-name my-production-stack
--enable-termination-protection

Disable termination protection (requires console access)

Disable termination protection (requires console access)

aws cloudformation update-termination-protection
--stack-name my-production-stack
--no-enable-termination-protection

**Enable via CloudFormation (for new stacks):**

```yaml
Resources:
  ProductionStack:
    Type: AWS::CloudFormation::Stack
    Properties:
      TemplateURL: https://s3.amazonaws.com/my-bucket/production.yaml
      TerminationProtection: true
Important Considerations:
  • Termination protection does not prevent stack updates
  • To delete a protected stack, you must first disable termination protection
  • Nested stacks inherit termination protection from parent stacks
  • Always enable for production and staging environments
aws cloudformation update-termination-protection
--stack-name my-production-stack
--no-enable-termination-protection

**通过CloudFormation启用(针对新栈):**

```yaml
Resources:
  ProductionStack:
    Type: AWS::CloudFormation::Stack
    Properties:
      TemplateURL: https://s3.amazonaws.com/my-bucket/production.yaml
      TerminationProtection: true
重要注意事项:
  • 终止保护不会阻止栈更新
  • 要删除受保护的栈,必须先禁用终止保护
  • 嵌套栈会继承父栈的终止保护
  • 始终为生产和预发布环境启用终止保护

Drift Detection

漂移检测

Drift detection identifies differences between your CloudFormation stack and the actual infrastructure. Run regular drift checks to ensure compliance.
Detect Drift on a Stack:
bash
undefined
漂移检测可识别CloudFormation栈与实际基础设施之间的差异,定期运行漂移检查以确保合规性。
检测栈的漂移:
bash
undefined

Detect drift on a stack

Detect drift on a stack

aws cloudformation detect-drift
--stack-name my-vpc-stack
aws cloudformation detect-drift
--stack-name my-vpc-stack

Check drift status

Check drift status

aws cloudformation describe-stack-drift-detection-status
--stack-drift-detection-id <detection-id>
aws cloudformation describe-stack-drift-detection-status
--stack-drift-detection-id <detection-id>

Get drift detection results

Get drift detection results

aws cloudformation describe-stack-resource-drifts
--stack-name my-vpc-stack

**Drift Status Values:**
- `IN_SYNC`: Resource matches the template
- `DRIFTED`: Resource has been modified outside CloudFormation
- `NOT_CHECKED`: Resource was not checked
- `UNKNOWN`: Drift status could not be determined

**Automated Drift Detection with Events:**

```yaml
aws cloudformation describe-stack-resource-drifts
--stack-name my-vpc-stack

**漂移状态值:**
- `IN_SYNC`:资源与模板一致
- `DRIFTED`:资源已在CloudFormation外部被修改
- `NOT_CHECKED`:未检查该资源
- `UNKNOWN`:无法确定漂移状态

**使用事件进行自动化漂移检测:**

```yaml

Use AWS Config for continuous drift monitoring

Use AWS Config for continuous drift monitoring

Resources: ConfigRule: Type: AWS::Config::ConfigRule Properties: ConfigRuleName: cloudformation-drift-detection Scope: ComplianceResourceTypes: - AWS::EC2::VPC - AWS::EC2::Subnet - AWS::EC2::SecurityGroup Source: Owner: CUSTOM_LAMBDA SourceIdentifier: Fn::GetAtt: [DriftDetectionFunction, Arn]

**Best Practices for Drift Detection:**
- Run drift detection weekly for production stacks
- Set up CloudWatch Events to trigger drift detection on schedule
- Document and address all drift immediately
- Use drift detection as part of change management process
Resources: ConfigRule: Type: AWS::Config::ConfigRule Properties: ConfigRuleName: cloudformation-drift-detection Scope: ComplianceResourceTypes: - AWS::EC2::VPC - AWS::EC2::Subnet - AWS::EC2::SecurityGroup Source: Owner: CUSTOM_LAMBDA SourceIdentifier: Fn::GetAtt: [DriftDetectionFunction, Arn]

**漂移检测最佳实践:**
- 每周对生产栈运行漂移检测
- 设置CloudWatch Events按计划触发漂移检测
- 立即记录并处理所有漂移
- 将漂移检测作为变更管理流程的一部分

Change Sets

变更集

Change Sets allow you to preview stack changes before applying them. This is essential for production deployments.
Create and Review a Change Set:
bash
undefined
变更集允许你在应用前预览栈变更,这对生产部署至关重要。
创建并查看变更集:
bash
undefined

Create a change set

Create a change set

aws cloudformation create-change-set
--stack-name my-vpc-stack
--template-body file://updated-template.yaml
--change-set-name vpc-update-changeset
--capabilities CAPABILITY_IAM
aws cloudformation create-change-set
--stack-name my-vpc-stack
--template-body file://updated-template.yaml
--change-set-name vpc-update-changeset
--capabilities CAPABILITY_IAM

List change sets

List change sets

aws cloudformation list-change-sets
--stack-name my-vpc-stack
aws cloudformation list-change-sets
--stack-name my-vpc-stack

Describe change set

Describe change set

aws cloudformation describe-change-set
--stack-name my-vpc-stack
--change-set-name vpc-update-changeset
aws cloudformation describe-change-set
--stack-name my-vpc-stack
--change-set-name vpc-update-changeset

Execute change set

Execute change set

aws cloudformation execute-change-set
--stack-name my-vpc-stack
--change-set-name vpc-update-changeset
aws cloudformation execute-change-set
--stack-name my-vpc-stack
--change-set-name vpc-update-changeset

Delete change set (if not executing)

Delete change set (if not executing)

aws cloudformation delete-change-set
--stack-name my-vpc-stack
--change-set-name vpc-update-changeset

**Change Set Types:**

| Type | Description | Use Case |
|------|-------------|----------|
| `UPDATE` | Standard update | Regular changes |
| `CREATE` | Creates new stack | Initial deployment |
| `IMPORT` | Imports existing resources | Lift-and-shift |

**Change Set Output Example:**

```json
{
  "ChangeSetId": "arn:aws:cloudformation:us-east-1:123456789:changeSet/...",
  "Changes": [
    {
      "Type": "Resource",
      "ResourceChange": {
        "Action": "Modify",
        "LogicalResourceId": "VPC",
        "PhysicalResourceId": "vpc-12345678",
        "Replacement": "False",
        "Details": [
          {
            "Target": {
              "Attribute": "Tags",
              "RequiresRecreation": "Never"
            },
            "Evaluation": "Static",
            "ChangeSource": "DirectModification"
          }
        ]
      }
    }
  ],
  "ExecutionStatus": "AVAILABLE",
  "Status": "CREATE_COMPLETE"
}
Best Practices for Change Sets:
  • Always create a change set before updating production stacks
  • Review all changes carefully before execution
  • Use meaningful change set names (e.g.,
    vpc-security-update-2024-01
    )
  • Execute change sets promptly after review
  • Set a TTL on change sets if your organization requires approval workflows
aws cloudformation delete-change-set
--stack-name my-vpc-stack
--change-set-name vpc-update-changeset

**变更集类型:**

| 类型 | 描述 | 适用场景 |
|------|-------------|----------|
| `UPDATE` | 标准更新 | 常规变更 |
| `CREATE` | 创建新栈 | 初始部署 |
| `IMPORT` | 导入现有资源 | 迁移场景 |

**变更集输出示例:**

```json
{
  "ChangeSetId": "arn:aws:cloudformation:us-east-1:123456789:changeSet/...",
  "Changes": [
    {
      "Type": "Resource",
      "ResourceChange": {
        "Action": "Modify",
        "LogicalResourceId": "VPC",
        "PhysicalResourceId": "vpc-12345678",
        "Replacement": "False",
        "Details": [
          {
            "Target": {
              "Attribute": "Tags",
              "RequiresRecreation": "Never"
            },
            "Evaluation": "Static",
            "ChangeSource": "DirectModification"
          }
        ]
      }
    }
  ],
  "ExecutionStatus": "AVAILABLE",
  "Status": "CREATE_COMPLETE"
}
变更集最佳实践:
  • 更新生产栈前始终创建变更集
  • 执行前仔细检查所有变更
  • 使用有意义的变更集名称(例如
    vpc-security-update-2024-01
  • 检查后立即执行变更集
  • 如果组织需要审批流程,可为变更集设置TTL

CI/CD Integration with Change Sets

与CI/CD集成的变更集

yaml
undefined
yaml
undefined

GitHub Actions workflow for safe deployments

GitHub Actions workflow for safe deployments

name: Deploy CloudFormation on: push: branches: [main]
jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4
  - name: Configure AWS Credentials
    uses: aws-actions/configure-aws-credentials@v4
    with:
      role-to-assume: arn:aws:iam::123456789:role/GitHubActionsRole
      aws-region: us-east-1

  - name: Create Change Set
    id: changeset
    run: |
      aws cloudformation create-change-set \
        --stack-name ${{ env.STACK_NAME }} \
        --template-body file://template.yaml \
        --change-set-name preview-changes \
        --capabilities CAPABILITY_IAM \
        --query 'Id' \
        --output text

  - name: Describe Change Set
    run: |
      aws cloudformation describe-change-set \
        --stack-name ${{ env.STACK_NAME }} \
        --change-set-name preview-changes

  - name: Execute Change Set (Manual approval required)
    if: github.event_name == 'push' && github.ref == 'refs/heads/main'
    run: |
      aws cloudformation execute-change-set \
        --stack-name ${{ env.STACK_NAME }} \
        --change-set-name preview-changes
undefined
name: Deploy CloudFormation on: push: branches: [main]
jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4
  - name: Configure AWS Credentials
    uses: aws-actions/configure-aws-credentials@v4
    with:
      role-to-assume: arn:aws:iam::123456789:role/GitHubActionsRole
      aws-region: us-east-1

  - name: Create Change Set
    id: changeset
    run: |
      aws cloudformation create-change-set \
        --stack-name ${{ env.STACK_NAME }} \
        --template-body file://template.yaml \
        --change-set-name preview-changes \
        --capabilities CAPABILITY_IAM \
        --query 'Id' \
        --output text

  - name: Describe Change Set
    run: |
      aws cloudformation describe-change-set \
        --stack-name ${{ env.STACK_NAME }} \
        --change-set-name preview-changes

  - name: Execute Change Set (Manual approval required)
    if: github.event_name == 'push' && github.ref == 'refs/heads/main'
    run: |
      aws cloudformation execute-change-set \
        --stack-name ${{ env.STACK_NAME }} \
        --change-set-name preview-changes
undefined

Related Resources

相关资源