aws-cloudformation-ec2

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

AWS CloudFormation EC2 Infrastructure

AWS CloudFormation EC2基础设施

Overview

概述

Create production-ready EC2 infrastructure using AWS CloudFormation templates. This skill covers EC2 instances (On-Demand and SPOT), Security Groups, IAM roles and instance profiles, Application Load Balancers (ALB), Target Groups, template structure best practices, parameter patterns, and cross-stack references for modular, reusable infrastructure as code.
使用AWS CloudFormation模板创建可用于生产环境的EC2基础设施。本内容涵盖EC2实例(按需实例和SPOT实例)、安全组、IAM角色和实例配置文件、应用负载均衡器(ALB)、目标组、模板结构最佳实践、参数模式,以及用于模块化、可重用基础设施即代码的跨栈引用。

When to Use

适用场景

Use this skill when:
  • Creating new EC2 instances (On-Demand or SPOT)
  • Configuring Security Groups for network access control
  • Creating IAM roles and instance profiles for EC2
  • Setting up Application Load Balancers (ALB) with target groups
  • Implementing template Parameters with AWS-specific types
  • Creating Outputs for cross-stack references
  • Organizing templates with Mappings and Conditions
  • Designing reusable, modular CloudFormation templates
在以下场景中使用本内容:
  • 创建新的EC2实例(按需实例或SPOT实例)
  • 配置用于网络访问控制的安全组
  • 为EC2创建IAM角色和实例配置文件
  • 设置带有目标组的应用负载均衡器(ALB)
  • 使用AWS特定类型实现模板Parameters
  • 创建用于跨栈引用的Outputs
  • 使用Mappings和Conditions组织模板
  • 设计可重用的模块化CloudFormation模板

Quick Start

快速开始

Basic EC2 Instance with Secure Configuration

带有安全配置的基础EC2实例

yaml
AWSTemplateFormatVersion: 2010-09-09
Description: Simple EC2 instance with secure SSH access

Parameters:
  LatestAmiId:
    Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
    Default: /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2

  InstanceType:
    Type: String
    Default: t3.micro
    AllowedValues:
      - t3.micro
      - t3.small
      - t3.medium

  KeyName:
    Type: AWS::EC2::KeyPair::KeyName
    Description: SSH key pair name

  SshLocation:
    Type: String
    Description: CIDR block for SSH access
    Default: 10.0.0.0/16
    AllowedPattern: ^([0-9]{1,3}\.){3}[0-9]{1,3}/[0-9]{1,2}$

Resources:
  InstanceSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Security group for EC2 instance
      VpcId: !Ref VpcId
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: !Ref SshLocation
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          CidrIp: 0.0.0.0/0

  Ec2Instance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !Ref LatestAmiId
      InstanceType: !Ref InstanceType
      KeyName: !Ref KeyName
      SecurityGroupIds:
        - !Ref InstanceSecurityGroup
      SubnetId: !Ref SubnetId
      Tags:
        - Key: Name
          Value: !Sub ${AWS::StackName}-instance

Outputs:
  InstanceId:
    Description: EC2 Instance ID
    Value: !Ref Ec2Instance

  PublicIp:
    Description: Public IP address
    Value: !GetAtt Ec2Instance.PublicIp
yaml
AWSTemplateFormatVersion: 2010-09-09
Description: Simple EC2 instance with secure SSH access

Parameters:
  LatestAmiId:
    Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
    Default: /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2

  InstanceType:
    Type: String
    Default: t3.micro
    AllowedValues:
      - t3.micro
      - t3.small
      - t3.medium

  KeyName:
    Type: AWS::EC2::KeyPair::KeyName
    Description: SSH key pair name

  SshLocation:
    Type: String
    Description: CIDR block for SSH access
    Default: 10.0.0.0/16
    AllowedPattern: ^([0-9]{1,3}\.){3}[0-9]{1,3}/[0-9]{1,2}$

Resources:
  InstanceSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Security group for EC2 instance
      VpcId: !Ref VpcId
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: !Ref SshLocation
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          CidrIp: 0.0.0.0/0

  Ec2Instance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !Ref LatestAmiId
      InstanceType: !Ref InstanceType
      KeyName: !Ref KeyName
      SecurityGroupIds:
        - !Ref InstanceSecurityGroup
      SubnetId: !Ref SubnetId
      Tags:
        - Key: Name
          Value: !Sub ${AWS::StackName}-instance

Outputs:
  InstanceId:
    Description: EC2 Instance ID
    Value: !Ref Ec2Instance

  PublicIp:
    Description: Public IP address
    Value: !GetAtt Ec2Instance.PublicIp

EC2 Instance with IAM Role

带有IAM角色的EC2实例

yaml
AWSTemplateFormatVersion: 2010-09-09
Description: EC2 instance with IAM role for S3 access

Resources:
  # IAM Role for EC2 with least privilege permissions
  Ec2Role:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: ec2.amazonaws.com
            Action: sts:AssumeRole
      ManagedPolicyArns: []
      Policies:
        - PolicyName: S3WriteAccess
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - s3:PutObject
                  - s3:GetObject
                Resource: !Sub "arn:aws:s3:::${S3BucketName}/*"

  # Instance Profile
  Ec2InstanceProfile:
    Type: AWS::IAM::InstanceProfile
    Properties:
      Roles:
        - !Ref Ec2Role
      InstanceProfileName: !Sub ${AWS::StackName}-profile

  # EC2 Instance
  Ec2Instance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !Ref LatestAmiId
      InstanceType: !Ref InstanceType
      IamInstanceProfile: !Ref Ec2InstanceProfile
      # ... other properties
yaml
AWSTemplateFormatVersion: 2010-09-09
Description: EC2 instance with IAM role for S3 access

Resources:
  # IAM Role for EC2 with least privilege permissions
  Ec2Role:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: ec2.amazonaws.com
            Action: sts:AssumeRole
      ManagedPolicyArns: []
      Policies:
        - PolicyName: S3WriteAccess
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - s3:PutObject
                  - s3:GetObject
                Resource: !Sub "arn:aws:s3:::${S3BucketName}/*"

  # Instance Profile
  Ec2InstanceProfile:
    Type: AWS::IAM::InstanceProfile
    Properties:
      Roles:
        - !Ref Ec2Role
      InstanceProfileName: !Sub ${AWS::StackName}-profile

  # EC2 Instance
  Ec2Instance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !Ref LatestAmiId
      InstanceType: !Ref InstanceType
      IamInstanceProfile: !Ref Ec2InstanceProfile
      # ... other properties

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 an EC2 instance with a security group
  and IAM role for running web applications. It includes:
  - EC2 instance configuration
  - Security group with HTTP/HTTPS access
  - IAM role with S3 access permissions
添加描述来记录模板的用途。必须出现在格式版本之后。
yaml
AWSTemplateFormatVersion: 2010-09-09
Description: >
  This template creates an EC2 instance with a security group
  and IAM role for running web applications. It includes:
  - EC2 instance configuration
  - Security group with HTTP/HTTPS access
  - IAM role with S3 access permissions

Metadata

元数据

Use
Metadata
for additional information about resources or parameters.
yaml
Metadata:
  AWS::CloudFormation::Interface:
    ParameterGroups:
      - Label:
          default: EC2 Configuration
        Parameters:
          - InstanceType
          - KeyName
      - Label:
          default: Network Configuration
        Parameters:
          - VpcId
          - SubnetId
    ParameterLabels:
      InstanceType:
        default: EC2 Instance Type
      KeyName:
        default: SSH Key Pair
使用
Metadata
添加关于资源或参数的额外信息。
yaml
Metadata:
  AWS::CloudFormation::Interface:
    ParameterGroups:
      - Label:
          default: EC2 Configuration
        Parameters:
          - InstanceType
          - KeyName
      - Label:
          default: Network Configuration
        Parameters:
          - VpcId
          - SubnetId
    ParameterLabels:
      InstanceType:
        default: EC2 Instance Type
      KeyName:
        default: SSH Key Pair

Resources Section

资源小节

The
Resources
section is the only required section. It defines AWS resources to provision.
yaml
Resources:
  MyInstance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: ami-0ff8a95407f89df2f
      InstanceType: t3.micro
      KeyName: my-key-pair
      Tags:
        - Key: Name
          Value: !Sub ${AWS::StackName}-instance
Resources
小节是唯一必填的小节。它定义了要创建的AWS资源。
yaml
Resources:
  MyInstance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: ami-0ff8a95407f89df2f
      InstanceType: t3.micro
      KeyName: my-key-pair
      Tags:
        - Key: Name
          Value: !Sub ${AWS::StackName}-instance

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

  AlbArn:
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer::Arn
    Description: Select an ALB
使用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

  AlbArn:
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer::Arn
    Description: Select an ALB

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

  LatestAmiIdARM:
    Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
    Description: Latest ARM AMI ID from SSM
    Default: /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-arm64-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

  LatestAmiIdARM:
    Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
    Description: Latest ARM AMI ID from SSM
    Default: /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-arm64-gp2

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

  VolumeSize:
    Type: Number
    Description: EBS volume size in GB
    Default: 20
    MinValue: 8
    MaxValue: 1000
添加约束来验证参数值。
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

  VolumeSize:
    Type: Number
    Description: EBS volume size in GB
    Default: 20
    MinValue: 8
    MaxValue: 1000

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
      EnableAutoScaling: false
    staging:
      InstanceType: t3.small
      MinInstances: 1
      MaxInstances: 3
      EnableAutoScaling: false
    production:
      InstanceType: t3.medium
      MinInstances: 2
      MaxInstances: 10
      EnableAutoScaling: true

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
      EnableAutoScaling: false
    staging:
      InstanceType: t3.small
      MinInstances: 1
      MaxInstances: 3
      EnableAutoScaling: false
    production:
      InstanceType: t3.medium
      MinInstances: 2
      MaxInstances: 10
      EnableAutoScaling: true

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:
  DeployAlb:
    Type: String
    Default: true
    AllowedValues:
      - true
      - false

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

  UseSpotInstance:
    Type: String
    Default: false
    AllowedValues:
      - true
      - false

Conditions:
  ShouldDeployAlb: !Equals [!Ref DeployAlb, true]
  IsProduction: !Equals [!Ref Environment, production]
  ShouldUseSpot: !Equals [!Ref UseSpotInstance, true]
  IsNotDevelopment: !Not [!Equals [!Ref Environment, development]]

Resources:
  ApplicationLoadBalancer:
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
    Condition: ShouldDeployAlb
    Properties:
      Scheme: internet-facing
      SecurityGroups:
        - !Ref AlbSecurityGroup
      Subnets: !Ref PublicSubnetIds

  ProductionScalingPolicy:
    Type: AWS::AutoScaling::ScalingPolicy
    Condition: IsProduction
    Properties:
      AutoScalingGroupName: !Ref AutoScalingGroup
      PolicyType: TargetTrackingScaling
      TargetTrackingConfiguration:
        PredefinedMetricSpecification:
          PredefinedMetricType: ASGAverageCPUUtilization
        TargetValue: 70.0
使用
Conditions
根据参数有条件地创建资源。
yaml
Parameters:
  DeployAlb:
    Type: String
    Default: true
    AllowedValues:
      - true
      - false

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

  UseSpotInstance:
    Type: String
    Default: false
    AllowedValues:
      - true
      - false

Conditions:
  ShouldDeployAlb: !Equals [!Ref DeployAlb, true]
  IsProduction: !Equals [!Ref Environment, production]
  ShouldUseSpot: !Equals [!Ref UseSpotInstance, true]
  IsNotDevelopment: !Not [!Equals [!Ref Environment, development]]

Resources:
  ApplicationLoadBalancer:
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
    Condition: ShouldDeployAlb
    Properties:
      Scheme: internet-facing
      SecurityGroups:
        - !Ref AlbSecurityGroup
      Subnets: !Ref PublicSubnetIds

  ProductionScalingPolicy:
    Type: AWS::AutoScaling::ScalingPolicy
    Condition: IsProduction
    Properties:
      AutoScalingGroupName: !Ref AutoScalingGroup
      PolicyType: TargetTrackingScaling
      TargetTrackingConfiguration:
        PredefinedMetricSpecification:
          PredefinedMetricType: ASGAverageCPUUtilization
        TargetValue: 70.0

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 with EC2

Resources:
  MyFunction:
    Type: AWS::Serverless::Function
    Properties:
      Handler: index.handler
      Runtime: nodejs18.x
      CodeUri: function/
使用
Transform
来处理宏,例如AWS::Serverless用于SAM模板。
yaml
AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::Serverless-2016-10-31
Description: SAM template for serverless application with EC2

Resources:
  MyFunction:
    Type: AWS::Serverless::Function
    Properties:
      Handler: index.handler
      Runtime: nodejs18.x
      CodeUri: function/

Outputs and Cross-Stack References

输出与跨栈引用

Basic Outputs

基础输出

yaml
Outputs:
  InstanceId:
    Description: EC2 Instance ID
    Value: !Ref Ec2Instance

  PublicIp:
    Description: Public IP address
    Value: !GetAtt Ec2Instance.PublicIp

  PrivateIp:
    Description: Private IP address
    Value: !GetAtt Ec2Instance.PrivateIp

  AvailabilityZone:
    Description: Availability Zone
    Value: !GetAtt Ec2Instance.AvailabilityZone
yaml
Outputs:
  InstanceId:
    Description: EC2 Instance ID
    Value: !Ref Ec2Instance

  PublicIp:
    Description: Public IP address
    Value: !GetAtt Ec2Instance.PublicIp

  PrivateIp:
    Description: Private IP address
    Value: !GetAtt Ec2Instance.PrivateIp

  AvailabilityZone:
    Description: Availability Zone
    Value: !GetAtt Ec2Instance.AvailabilityZone

Exporting Values for Cross-Stack References

导出值用于跨栈引用

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

  SecurityGroupId:
    Description: Security Group ID for other stacks
    Value: !Ref InstanceSecurityGroup
    Export:
      Name: !Sub ${AWS::StackName}-SecurityGroupId

  InstanceRoleArn:
    Description: IAM Role ARN for other stacks
    Value: !GetAtt Ec2Role.Arn
    Export:
      Name: !Sub ${AWS::StackName}-InstanceRoleArn

  TargetGroupArn:
    Description: Target Group ARN for other stacks
    Value: !Ref ApplicationTargetGroup
    Export:
      Name: !Sub ${AWS::StackName}-TargetGroupArn
导出值以便其他栈可以导入它们。
yaml
Outputs:
  InstanceId:
    Description: EC2 Instance ID for other stacks
    Value: !Ref Ec2Instance
    Export:
      Name: !Sub ${AWS::StackName}-InstanceId

  SecurityGroupId:
    Description: Security Group ID for other stacks
    Value: !Ref InstanceSecurityGroup
    Export:
      Name: !Sub ${AWS::StackName}-SecurityGroupId

  InstanceRoleArn:
    Description: IAM Role ARN for other stacks
    Value: !GetAtt Ec2Role.Arn
    Export:
      Name: !Sub ${AWS::StackName}-InstanceRoleArn

  TargetGroupArn:
    Description: Target Group ARN for other stacks
    Value: !Ref ApplicationTargetGroup
    Export:
      Name: !Sub ${AWS::StackName}-TargetGroupArn

Importing Values in Another Stack

在另一个栈中导入值

yaml
Parameters:
  VpcId:
    Type: AWS::EC2::VPC::Id
    Description: VPC ID from network stack

  SecurityGroupId:
    Type: AWS::EC2::SecurityGroup::Id
    Description: Security Group ID from security stack

  InstanceRoleArn:
    Type: String
    Description: IAM Role ARN from security stack

  # 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

  Instance:
    Type: AWS::EC2::Instance
    Properties:
      IamInstanceProfile: !ImportValue
        Fn::Sub: ${SecurityStackName}-InstanceRoleArn
yaml
Parameters:
  VpcId:
    Type: AWS::EC2::VPC::Id
    Description: VPC ID from network stack

  SecurityGroupId:
    Type: AWS::EC2::SecurityGroup::Id
    Description: Security Group ID from security stack

  InstanceRoleArn:
    Type: String
    Description: IAM Role ARN from security stack

  # 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

  Instance:
    Type: AWS::EC2::Instance
    Properties:
      IamInstanceProfile: !ImportValue
        Fn::Sub: ${SecurityStackName}-InstanceRoleArn

Cross-Stack Reference Pattern

跨栈引用模式

Create a dedicated security stack that exports values:
yaml
undefined
创建一个专用的安全栈来导出值:
yaml
undefined

security-stack.yaml

security-stack.yaml

AWSTemplateFormatVersion: 2010-09-09 Description: Security resources stack
Resources: InstanceSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: Security group for EC2 instances VpcId: !Ref VpcId SecurityGroupIngress: - IpProtocol: tcp FromPort: 80 ToPort: 80 CidrIp: 0.0.0.0/0
Ec2Role: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Principal: Service: ec2.amazonaws.com Action: sts:AssumeRole
Outputs: SecurityGroupId: Value: !Ref InstanceSecurityGroup Export: Name: !Sub ${AWS::StackName}-SecurityGroupId
InstanceRoleArn: Value: !GetAtt Ec2Role.Arn Export: Name: !Sub ${AWS::StackName}-InstanceRoleArn

Application stack imports these values:

```yaml
AWSTemplateFormatVersion: 2010-09-09 Description: Security resources stack
Resources: InstanceSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: Security group for EC2 instances VpcId: !Ref VpcId SecurityGroupIngress: - IpProtocol: tcp FromPort: 80 ToPort: 80 CidrIp: 0.0.0.0/0
Ec2Role: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Principal: Service: ec2.amazonaws.com Action: sts:AssumeRole
Outputs: SecurityGroupId: Value: !Ref InstanceSecurityGroup Export: Name: !Sub ${AWS::StackName}-SecurityGroupId
InstanceRoleArn: Value: !GetAtt Ec2Role.Arn Export: Name: !Sub ${AWS::StackName}-InstanceRoleArn

应用栈导入这些值:

```yaml

application-stack.yaml

application-stack.yaml

AWSTemplateFormatVersion: 2010-09-09 Description: Application stack that imports from security stack
Parameters: SecurityStackName: Type: String Description: Name of the security stack Default: security-stack
Resources: Ec2Instance: Type: AWS::EC2::Instance Properties: ImageId: !Ref AmiId InstanceType: !Ref InstanceType SecurityGroupIds: - !ImportValue Fn::Sub: ${SecurityStackName}-SecurityGroupId IamInstanceProfile: !ImportValue Fn::Sub: ${SecurityStackName}-InstanceRoleArn
undefined
AWSTemplateFormatVersion: 2010-09-09 Description: Application stack that imports from security stack
Parameters: SecurityStackName: Type: String Description: Name of the security stack Default: security-stack
Resources: Ec2Instance: Type: AWS::EC2::Instance Properties: ImageId: !Ref AmiId InstanceType: !Ref InstanceType SecurityGroupIds: - !ImportValue Fn::Sub: ${SecurityStackName}-SecurityGroupId IamInstanceProfile: !ImportValue Fn::Sub: ${SecurityStackName}-InstanceRoleArn
undefined

EC2 Instances

EC2实例

Basic Instance Configuration

基础实例配置

yaml
Resources:
  Ec2Instance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !Ref AmiId
      InstanceType: !Ref InstanceType
      KeyName: !Ref KeyName
      SubnetId: !Ref SubnetId
      SecurityGroupIds:
        - !Ref SecurityGroup
      UserData:
        Fn::Base64: |
          #!/bin/bash
          yum update -y
          yum install -y httpd
          systemctl start httpd
      Tags:
        - Key: Name
          Value: !Sub ${AWS::StackName}-instance
        - Key: Environment
          Value: !Ref EnvironmentName
yaml
Resources:
  Ec2Instance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !Ref AmiId
      InstanceType: !Ref InstanceType
      KeyName: !Ref KeyName
      SubnetId: !Ref SubnetId
      SecurityGroupIds:
        - !Ref SecurityGroup
      UserData:
        Fn::Base64: |
          #!/bin/bash
          yum update -y
          yum install -y httpd
          systemctl start httpd
      Tags:
        - Key: Name
          Value: !Sub ${AWS::StackName}-instance
        - Key: Environment
          Value: !Ref EnvironmentName

Instance with Multiple Volumes

带有多块卷的实例

yaml
Resources:
  Ec2Instance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !Ref AmiId
      InstanceType: !Ref InstanceType
      BlockDeviceMappings:
        - DeviceName: /dev/xvda
          Ebs:
            VolumeSize: 20
            DeleteOnTermination: true
            VolumeType: gp3
        - DeviceName: /dev/xvdh
          Ebs:
            VolumeSize: 50
            DeleteOnTermination: false
            VolumeType: gp3
        - DeviceName: /dev/xvdi
          Ebs:
            VolumeSize: 100
            DeleteOnTermination: false
            VolumeType: st1
yaml
Resources:
  Ec2Instance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !Ref AmiId
      InstanceType: !Ref InstanceType
      BlockDeviceMappings:
        - DeviceName: /dev/xvda
          Ebs:
            VolumeSize: 20
            DeleteOnTermination: true
            VolumeType: gp3
        - DeviceName: /dev/xvdh
          Ebs:
            VolumeSize: 50
            DeleteOnTermination: false
            VolumeType: gp3
        - DeviceName: /dev/xvdi
          Ebs:
            VolumeSize: 100
            DeleteOnTermination: false
            VolumeType: st1

Instance with Detailed Monitoring

带有详细监控的实例

yaml
Resources:
  Ec2Instance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !Ref AmiId
      InstanceType: !Ref InstanceType
      Monitoring: true
      Metrics:
        CollectionInterval: 60
yaml
Resources:
  Ec2Instance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !Ref AmiId
      InstanceType: !Ref InstanceType
      Monitoring: true
      Metrics:
        CollectionInterval: 60

Instance with Placement

带有放置组的实例

yaml
Resources:
  Ec2Instance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !Ref AmiId
      InstanceType: !Ref InstanceType
      Placement:
        AvailabilityZone: !Select [0, !GetAZs '']
        GroupName: !Ref PlacementGroup
        Tenancy: default
yaml
Resources:
  Ec2Instance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !Ref AmiId
      InstanceType: !Ref InstanceType
      Placement:
        AvailabilityZone: !Select [0, !GetAZs '']
        GroupName: !Ref PlacementGroup
        Tenancy: default

SPOT Instances

SPOT实例

SPOT Fleet

SPOT实例集

yaml
AWSTemplateFormatVersion: 2010-09-09
Description: SPOT Fleet for cost-optimized instances

Parameters:
  MaxPrice:
    Type: Number
    Default: 0.05
    Description: Maximum price per instance hour

Resources:
  SpotFleet:
    Type: AWS::EC2::SpotFleet
    Properties:
      SpotFleetRequestConfigData:
        TargetCapacity: 10
        IamFleetRole: !GetAtt SpotFleetRole.Arn
        LaunchSpecifications:
          - InstanceType: t3.micro
            ImageId: !Ref AmiId
            SubnetId: !Ref SubnetId
            WeightedCapacity: 1
          - InstanceType: t3.small
            ImageId: !Ref AmiId
            SubnetId: !Ref SubnetId
            WeightedCapacity: 2
        AllocationStrategy: lowestPrice
        SpotPrice: !Sub ${MaxPrice}

  SpotFleetRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: spotfleet.amazonaws.com
            Action: sts:AssumeRole
      Policies:
        - PolicyName: SpotFleetPolicy
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - ec2:DescribeInstances
                  - ec2:DescribeImages
                Resource: "*"
yaml
AWSTemplateFormatVersion: 2010-09-09
Description: SPOT Fleet for cost-optimized instances

Parameters:
  MaxPrice:
    Type: Number
    Default: 0.05
    Description: Maximum price per instance hour

Resources:
  SpotFleet:
    Type: AWS::EC2::SpotFleet
    Properties:
      SpotFleetRequestConfigData:
        TargetCapacity: 10
        IamFleetRole: !GetAtt SpotFleetRole.Arn
        LaunchSpecifications:
          - InstanceType: t3.micro
            ImageId: !Ref AmiId
            SubnetId: !Ref SubnetId
            WeightedCapacity: 1
          - InstanceType: t3.small
            ImageId: !Ref AmiId
            SubnetId: !Ref SubnetId
            WeightedCapacity: 2
        AllocationStrategy: lowestPrice
        SpotPrice: !Sub ${MaxPrice}

  SpotFleetRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: spotfleet.amazonaws.com
            Action: sts:AssumeRole
      Policies:
        - PolicyName: SpotFleetPolicy
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - ec2:DescribeInstances
                  - ec2:DescribeImages
                Resource: "*"

SPOT Instance Request

SPOT实例请求

yaml
Resources:
  SpotRequest:
    Type: AWS::EC2::SpotFleet
    Properties:
      SpotFleetRequestConfigData:
        TargetCapacity: 1
        IamFleetRole: !GetAtt SpotFleetRole.Arn
        LaunchSpecifications:
          - InstanceType: t3.medium
            ImageId: !Ref AmiId
            SubnetId: !Ref SubnetId
            KeyName: !Ref KeyName
        Type: persistent
yaml
Resources:
  SpotRequest:
    Type: AWS::EC2::SpotFleet
    Properties:
      SpotFleetRequestConfigData:
        TargetCapacity: 1
        IamFleetRole: !GetAtt SpotFleetRole.Arn
        LaunchSpecifications:
          - InstanceType: t3.medium
            ImageId: !Ref AmiId
            SubnetId: !Ref SubnetId
            KeyName: !Ref KeyName
        Type: persistent

SPOT Instance with Fallback

带有 fallback 的SPOT实例

yaml
Resources:
  OnDemandInstance:
    Type: AWS::EC2::Instance
    Condition: IsNotSpot
    Properties:
      ImageId: !Ref AmiId
      InstanceType: !Ref InstanceType

  SpotInstance:
    Type: AWS::EC2::SpotFleet
    Condition: UseSpot
    Properties:
      SpotFleetRequestConfigData:
        TargetCapacity: 1
        IamFleetRole: !GetAtt SpotFleetRole.Arn
        LaunchSpecifications:
          - InstanceType: t3.medium
            ImageId: !Ref AmiId
            SubnetId: !Ref SubnetId
yaml
Resources:
  OnDemandInstance:
    Type: AWS::EC2::Instance
    Condition: IsNotSpot
    Properties:
      ImageId: !Ref AmiId
      InstanceType: !Ref InstanceType

  SpotInstance:
    Type: AWS::EC2::SpotFleet
    Condition: UseSpot
    Properties:
      SpotFleetRequestConfigData:
        TargetCapacity: 1
        IamFleetRole: !GetAtt SpotFleetRole.Arn
        LaunchSpecifications:
          - InstanceType: t3.medium
            ImageId: !Ref AmiId
            SubnetId: !Ref SubnetId

Security Groups

安全组

Basic Security Group

基础安全组

yaml
Resources:
  WebSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Security group for web servers
      VpcId: !Ref VpcId
      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
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: 10.0.0.0/16
      SecurityGroupEgress:
        - IpProtocol: tcp
          FromPort: 443
          ToPort: 443
          CidrIp: 0.0.0.0/0
      Tags:
        - Key: Name
          Value: !Sub ${AWS::StackName}-web-sg
yaml
Resources:
  WebSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Security group for web servers
      VpcId: !Ref VpcId
      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
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: 10.0.0.0/16
      SecurityGroupEgress:
        - IpProtocol: tcp
          FromPort: 443
          ToPort: 443
          CidrIp: 0.0.0.0/0
      Tags:
        - Key: Name
          Value: !Sub ${AWS::StackName}-web-sg

Security Group with Self Reference

带有自引用的安全组

yaml
Resources:
  AppSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Security group for application
      VpcId: !Ref VpcId
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 8080
          ToPort: 8080
          SourceSecurityGroupId: !Ref LoadBalancerSecurityGroup
      Tags:
        - Key: Name
          Value: !Sub ${AWS::StackName}-app-sg

  DatabaseSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Security group for database
      VpcId: !Ref VpcId
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 5432
          ToPort: 5432
          SourceSecurityGroupId: !Ref AppSecurityGroup
      Tags:
        - Key: Name
          Value: !Sub ${AWS::StackName}-db-sg
yaml
Resources:
  AppSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Security group for application
      VpcId: !Ref VpcId
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 8080
          ToPort: 8080
          SourceSecurityGroupId: !Ref LoadBalancerSecurityGroup
      Tags:
        - Key: Name
          Value: !Sub ${AWS::StackName}-app-sg

  DatabaseSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Security group for database
      VpcId: !Ref VpcId
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 5432
          ToPort: 5432
          SourceSecurityGroupId: !Ref AppSecurityGroup
      Tags:
        - Key: Name
          Value: !Sub ${AWS::StackName}-db-sg

Security Group for ALB

用于ALB的安全组

yaml
Resources:
  AlbSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Security group for Application Load Balancer
      VpcId: !Ref VpcId
      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
      SecurityGroupEgress:
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          SourceSecurityGroupId: !Ref AppSecurityGroup
        - IpProtocol: tcp
          FromPort: 443
          ToPort: 443
          SourceSecurityGroupId: !Ref AppSecurityGroup
yaml
Resources:
  AlbSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Security group for Application Load Balancer
      VpcId: !Ref VpcId
      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
      SecurityGroupEgress:
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          SourceSecurityGroupId: !Ref AppSecurityGroup
        - IpProtocol: tcp
          FromPort: 443
          ToPort: 443
          SourceSecurityGroupId: !Ref AppSecurityGroup

IAM Roles

IAM角色

EC2 IAM Role with Least Privilege

遵循最小权限原则的EC2 IAM角色

yaml
Resources:
  Ec2Role:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: ec2.amazonaws.com
            Action: sts:AssumeRole
      ManagedPolicyArns: []
      Policies:
        - PolicyName: S3Access
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - s3:GetObject
                  - s3:PutObject
                  - s3:DeleteObject
                Resource: !Sub "arn:aws:s3:::${S3BucketName}/*"
        - PolicyName: CloudWatchLogs
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - logs:CreateLogGroup
                  - logs:CreateLogStream
                  - logs:PutLogEvents
                  - logs:DescribeLogStreams
                Resource: !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/ec2/${EnvironmentName}/*"

  Ec2InstanceProfile:
    Type: AWS::IAM::InstanceProfile
    Properties:
      Roles:
        - !Ref Ec2Role
      InstanceProfileName: !Sub ${AWS::StackName}-profile
yaml
Resources:
  Ec2Role:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: ec2.amazonaws.com
            Action: sts:AssumeRole
      ManagedPolicyArns: []
      Policies:
        - PolicyName: S3Access
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - s3:GetObject
                  - s3:PutObject
                  - s3:DeleteObject
                Resource: !Sub "arn:aws:s3:::${S3BucketName}/*"
        - PolicyName: CloudWatchLogs
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - logs:CreateLogGroup
                  - logs:CreateLogStream
                  - logs:PutLogEvents
                  - logs:DescribeLogStreams
                Resource: !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/ec2/${EnvironmentName}/*"

  Ec2InstanceProfile:
    Type: AWS::IAM::InstanceProfile
    Properties:
      Roles:
        - !Ref Ec2Role
      InstanceProfileName: !Sub ${AWS::StackName}-profile

Role for Systems Manager

用于Systems Manager的角色

yaml
Resources:
  SsmRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: ec2.amazonaws.com
            Action: sts:AssumeRole
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
      Policies:
        - PolicyName: S3ReadAccess
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - s3:GetObject
                Resource: !Sub "arn:aws:s3:::${S3BucketName}/*"
yaml
Resources:
  SsmRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: ec2.amazonaws.com
            Action: sts:AssumeRole
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
      Policies:
        - PolicyName: S3ReadAccess
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - s3:GetObject
                Resource: !Sub "arn:aws:s3:::${S3BucketName}/*"

Application Load Balancer (ALB)

应用负载均衡器(ALB)

Basic ALB

基础ALB

yaml
Resources:
  ApplicationLoadBalancer:
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
    Properties:
      Name: !Sub ${AWS::StackName}-alb
      Scheme: internet-facing
      SecurityGroups:
        - !Ref AlbSecurityGroup
      Subnets:
        - !Ref PublicSubnet1
        - !Ref PublicSubnet2
      Type: application

  ApplicationTargetGroup:
    Type: AWS::ElasticLoadBalancingV2::TargetGroup
    Properties:
      Name: !Sub ${AWS::StackName}-tg
      Port: 80
      Protocol: HTTP
      VpcId: !Ref VpcId
      TargetType: instance
      HealthCheckPath: /health
      HealthCheckIntervalSeconds: 30
      HealthCheckTimeoutSeconds: 5
      HealthyThresholdCount: 2
      UnhealthyThresholdCount: 3
      Tags:
        - Key: Name
          Value: !Sub ${AWS::StackName}-tg

  ApplicationListener:
    Type: AWS::ElasticLoadBalancingV2::Listener
    Properties:
      DefaultActions:
        - Type: forward
          TargetGroupArn: !Ref ApplicationTargetGroup
      LoadBalancerArn: !Ref ApplicationLoadBalancer
      Port: 80
      Protocol: HTTP
yaml
Resources:
  ApplicationLoadBalancer:
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
    Properties:
      Name: !Sub ${AWS::StackName}-alb
      Scheme: internet-facing
      SecurityGroups:
        - !Ref AlbSecurityGroup
      Subnets:
        - !Ref PublicSubnet1
        - !Ref PublicSubnet2
      Type: application

  ApplicationTargetGroup:
    Type: AWS::ElasticLoadBalancingV2::TargetGroup
    Properties:
      Name: !Sub ${AWS::StackName}-tg
      Port: 80
      Protocol: HTTP
      VpcId: !Ref VpcId
      TargetType: instance
      HealthCheckPath: /health
      HealthCheckIntervalSeconds: 30
      HealthCheckTimeoutSeconds: 5
      HealthyThresholdCount: 2
      UnhealthyThresholdCount: 3
      Tags:
        - Key: Name
          Value: !Sub ${AWS::StackName}-tg

  ApplicationListener:
    Type: AWS::ElasticLoadBalancingV2::Listener
    Properties:
      DefaultActions:
        - Type: forward
          TargetGroupArn: !Ref ApplicationTargetGroup
      LoadBalancerArn: !Ref ApplicationLoadBalancer
      Port: 80
      Protocol: HTTP

ALB with HTTPS

带有HTTPS的ALB

yaml
Resources:
  ApplicationLoadBalancer:
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
    Properties:
      Name: !Sub ${AWS::StackName}-alb
      Scheme: internet-facing
      SecurityGroups:
        - !Ref AlbSecurityGroup
      Subnets:
        - !Ref PublicSubnet1
        - !Ref PublicSubnet2

  ApplicationTargetGroup:
    Type: AWS::ElasticLoadBalancingV2::TargetGroup
    Properties:
      Name: !Sub ${AWS::StackName}-tg
      Port: 443
      Protocol: HTTPS
      VpcId: !Ref VpcId
      TargetType: instance
      HealthCheckPath: /health
      HealthCheckProtocol: HTTPS

  ApplicationListener:
    Type: AWS::ElasticLoadBalancingV2::Listener
    Properties:
      DefaultActions:
        - Type: forward
          TargetGroupArn: !Ref ApplicationTargetGroup
      LoadBalancerArn: !Ref ApplicationLoadBalancer
      Port: 443
      Protocol: HTTPS
      Certificates:
        - CertificateArn: !Ref CertificateArn

  ApplicationListenerHttpRedirect:
    Type: AWS::ElasticLoadBalancingV2::Listener
    Properties:
      DefaultActions:
        - Type: redirect
          RedirectConfig:
            Host: "#{host}"
            Path: "/#{path}"
            Port: "443"
            Protocol: "HTTPS"
            Query: "#{query}"
            StatusCode: HTTP_301
      LoadBalancerArn: !Ref ApplicationLoadBalancer
      Port: 80
      Protocol: HTTP
yaml
Resources:
  ApplicationLoadBalancer:
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
    Properties:
      Name: !Sub ${AWS::StackName}-alb
      Scheme: internet-facing
      SecurityGroups:
        - !Ref AlbSecurityGroup
      Subnets:
        - !Ref PublicSubnet1
        - !Ref PublicSubnet2

  ApplicationTargetGroup:
    Type: AWS::ElasticLoadBalancingV2::TargetGroup
    Properties:
      Name: !Sub ${AWS::StackName}-tg
      Port: 443
      Protocol: HTTPS
      VpcId: !Ref VpcId
      TargetType: instance
      HealthCheckPath: /health
      HealthCheckProtocol: HTTPS

  ApplicationListener:
    Type: AWS::ElasticLoadBalancingV2::Listener
    Properties:
      DefaultActions:
        - Type: forward
          TargetGroupArn: !Ref ApplicationTargetGroup
      LoadBalancerArn: !Ref ApplicationLoadBalancer
      Port: 443
      Protocol: HTTPS
      Certificates:
        - CertificateArn: !Ref CertificateArn

  ApplicationListenerHttpRedirect:
    Type: AWS::ElasticLoadBalancingV2::Listener
    Properties:
      DefaultActions:
        - Type: redirect
          RedirectConfig:
            Host: "#{host}"
            Path: "/#{path}"
            Port: "443"
            Protocol: "HTTPS"
            Query: "#{query}"
            StatusCode: HTTP_301
      LoadBalancerArn: !Ref ApplicationLoadBalancer
      Port: 80
      Protocol: HTTP

ALB with Multiple Target Groups

带有多个目标组的ALB

yaml
Resources:
  ApplicationLoadBalancer:
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
    Properties:
      Name: !Sub ${AWS::StackName}-alb
      Scheme: internet-facing
      SecurityGroups:
        - !Ref AlbSecurityGroup
      Subnets:
        - !Ref PublicSubnet1
        - !Ref PublicSubnet2

  ApiTargetGroup:
    Type: AWS::ElasticLoadBalancingV2::TargetGroup
    Properties:
      Name: !Sub ${AWS::StackName}-api-tg
      Port: 8080
      Protocol: HTTP
      VpcId: !Ref VpcId
      HealthCheckPath: /actuator/health

  WebTargetGroup:
    Type: AWS::ElasticLoadBalancingV2::TargetGroup
    Properties:
      Name: !Sub ${AWS::StackName}-web-tg
      Port: 80
      Protocol: HTTP
      VpcId: !Ref VpcId
      HealthCheckPath: /health

  ApiListenerRule:
    Type: AWS::ElasticLoadBalancingV2::ListenerRule
    Properties:
      Actions:
        - Type: forward
          TargetGroupArn: !Ref ApiTargetGroup
      Conditions:
        - Field: path-pattern
          Values:
            - /api/*
            - /v1/*
      ListenerArn: !Ref ApplicationListener
      Priority: 10

  WebListenerRule:
    Type: AWS::ElasticLoadBalancingV2::ListenerRule
    Properties:
      Actions:
        - Type: forward
          TargetGroupArn: !Ref WebTargetGroup
      Conditions:
        - Field: path-pattern
          Values:
            - /*
      ListenerArn: !Ref ApplicationListener
      Priority: 100
yaml
Resources:
  ApplicationLoadBalancer:
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
    Properties:
      Name: !Sub ${AWS::StackName}-alb
      Scheme: internet-facing
      SecurityGroups:
        - !Ref AlbSecurityGroup
      Subnets:
        - !Ref PublicSubnet1
        - !Ref PublicSubnet2

  ApiTargetGroup:
    Type: AWS::ElasticLoadBalancingV2::TargetGroup
    Properties:
      Name: !Sub ${AWS::StackName}-api-tg
      Port: 8080
      Protocol: HTTP
      VpcId: !Ref VpcId
      HealthCheckPath: /actuator/health

  WebTargetGroup:
    Type: AWS::ElasticLoadBalancingV2::TargetGroup
    Properties:
      Name: !Sub ${AWS::StackName}-web-tg
      Port: 80
      Protocol: HTTP
      VpcId: !Ref VpcId
      HealthCheckPath: /health

  ApiListenerRule:
    Type: AWS::ElasticLoadBalancingV2::ListenerRule
    Properties:
      Actions:
        - Type: forward
          TargetGroupArn: !Ref ApiTargetGroup
      Conditions:
        - Field: path-pattern
          Values:
            - /api/*
            - /v1/*
      ListenerArn: !Ref ApplicationListener
      Priority: 10

  WebListenerRule:
    Type: AWS::ElasticLoadBalancingV2::ListenerRule
    Properties:
      Actions:
        - Type: forward
          TargetGroupArn: !Ref WebTargetGroup
      Conditions:
        - Field: path-pattern
          Values:
            - /*
      ListenerArn: !Ref ApplicationListener
      Priority: 100

ALB with Cross-Zone Load Balancing

带有跨区域负载均衡的ALB

yaml
Resources:
  ApplicationLoadBalancer:
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
    Properties:
      Name: !Sub ${AWS::StackName}-alb
      Scheme: internet-facing
      SecurityGroups:
        - !Ref AlbSecurityGroup
      Subnets:
        - !Ref PublicSubnet1
        - !Ref PublicSubnet2
      LoadBalancerAttributes:
        - Key: load_balancing.cross_zone.enabled
          Value: true
yaml
Resources:
  ApplicationLoadBalancer:
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
    Properties:
      Name: !Sub ${AWS::StackName}-alb
      Scheme: internet-facing
      SecurityGroups:
        - !Ref AlbSecurityGroup
      Subnets:
        - !Ref PublicSubnet1
        - !Ref PublicSubnet2
      LoadBalancerAttributes:
        - Key: load_balancing.cross_zone.enabled
          Value: true

Complete Example

完整示例

Full EC2 Stack with ALB

带有ALB的完整EC2栈

yaml
AWSTemplateFormatVersion: 2010-09-09
Description: Complete EC2 stack with ALB, security groups, and IAM role

Parameters:
  EnvironmentName:
    Type: String
    Default: production

  LatestAmiId:
    Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
    Default: /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2

  InstanceType:
    Type: String
    Default: t3.micro
    AllowedValues:
      - t3.micro
      - t3.small
      - t3.medium
      - t3.large

  VpcCidr:
    Type: String
    Default: 10.0.0.0/16

Resources:
  # VPC
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: !Ref VpcCidr
      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

  # 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

  # Security Group for ALB
  AlbSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Security group for ALB
      VpcId: !Ref VPC
      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 ${EnvironmentName}-alb-sg
        - Key: Environment
          Value: !Ref EnvironmentName

  # Security Group for EC2
  InstanceSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Security group for EC2 instances
      VpcId: !Ref VPC
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          SourceSecurityGroupId: !Ref AlbSecurityGroup
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: 10.0.0.0/16
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-instance-sg
        - Key: Environment
          Value: !Ref EnvironmentName

  # IAM Role with specific permissions
  Ec2Role:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: ec2.amazonaws.com
            Action: sts:AssumeRole
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
      Policies:
        - PolicyName: S3Access
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - s3:GetObject
                  - s3:PutObject
                Resource: !Sub "arn:aws:s3:::${S3BucketName}/*"
        - PolicyName: CloudWatchLogs
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - logs:CreateLogGroup
                  - logs:CreateLogStream
                  - logs:PutLogEvents
                Resource: !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/ec2/${EnvironmentName}/*"
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-ec2-role

  Ec2InstanceProfile:
    Type: AWS::IAM::InstanceProfile
    Properties:
      Roles:
        - !Ref Ec2Role

  # Application Load Balancer
  ApplicationLoadBalancer:
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
    Properties:
      Name: !Sub ${EnvironmentName}-alb
      Scheme: internet-facing
      SecurityGroups:
        - !Ref AlbSecurityGroup
      Subnets:
        - !Ref PublicSubnet1
        - !Ref PublicSubnet2
      Type: application

  ApplicationTargetGroup:
    Type: AWS::ElasticLoadBalancingV2::TargetGroup
    Properties:
      Name: !Sub ${EnvironmentName}-tg
      Port: 80
      Protocol: HTTP
      VpcId: !Ref VPC
      TargetType: instance
      HealthCheckPath: /health
      HealthCheckIntervalSeconds: 30
      HealthCheckTimeoutSeconds: 5
      HealthyThresholdCount: 2
      UnhealthyThresholdCount: 3
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-tg

  ApplicationListener:
    Type: AWS::ElasticLoadBalancingV2::Listener
    Properties:
      DefaultActions:
        - Type: forward
          TargetGroupArn: !Ref ApplicationTargetGroup
      LoadBalancerArn: !Ref ApplicationLoadBalancer
      Port: 80
      Protocol: HTTP

  # EC2 Instance
  Ec2Instance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !Ref LatestAmiId
      InstanceType: !Ref InstanceType
      IamInstanceProfile: !Ref Ec2InstanceProfile
      SecurityGroupIds:
        - !Ref InstanceSecurityGroup
      SubnetId: !Ref PublicSubnet1
      UserData:
        Fn::Base64: |
          #!/bin/bash
          yum update -y
          yum install -y httpd
          systemctl start httpd
          systemctl enable httpd
          echo "<h1>Hello from $(hostname)</h1>" > /var/www/html/index.html
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-instance
        - Key: Environment
          Value: !Ref EnvironmentName

Outputs:
  InstanceId:
    Description: EC2 Instance ID
    Value: !Ref Ec2Instance

  InstancePublicIp:
    Description: EC2 Instance Public IP
    Value: !GetAtt Ec2Instance.PublicIp

  LoadBalancerDnsName:
    Description: ALB DNS Name
    Value: !GetAtt ApplicationLoadBalancer.DNSName

  TargetGroupArn:
    Description: Target Group ARN
    Value: !Ref ApplicationTargetGroup

  SecurityGroupId:
    Description: Instance Security Group ID
    Value: !Ref InstanceSecurityGroup

  RoleArn:
    Description: IAM Role ARN
    Value: !GetAtt Ec2Role.Arn
yaml
AWSTemplateFormatVersion: 2010-09-09
Description: Complete EC2 stack with ALB, security groups, and IAM role

Parameters:
  EnvironmentName:
    Type: String
    Default: production

  LatestAmiId:
    Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
    Default: /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2

  InstanceType:
    Type: String
    Default: t3.micro
    AllowedValues:
      - t3.micro
      - t3.small
      - t3.medium
      - t3.large

  VpcCidr:
    Type: String
    Default: 10.0.0.0/16

Resources:
  # VPC
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: !Ref VpcCidr
      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

  # 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

  # Security Group for ALB
  AlbSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Security group for ALB
      VpcId: !Ref VPC
      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 ${EnvironmentName}-alb-sg
        - Key: Environment
          Value: !Ref EnvironmentName

  # Security Group for EC2
  InstanceSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Security group for EC2 instances
      VpcId: !Ref VPC
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          SourceSecurityGroupId: !Ref AlbSecurityGroup
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: 10.0.0.0/16
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-instance-sg
        - Key: Environment
          Value: !Ref EnvironmentName

  # IAM Role with specific permissions
  Ec2Role:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: ec2.amazonaws.com
            Action: sts:AssumeRole
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
      Policies:
        - PolicyName: S3Access
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - s3:GetObject
                  - s3:PutObject
                Resource: !Sub "arn:aws:s3:::${S3BucketName}/*"
        - PolicyName: CloudWatchLogs
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - logs:CreateLogGroup
                  - logs:CreateLogStream
                  - logs:PutLogEvents
                Resource: !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/ec2/${EnvironmentName}/*"
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-ec2-role

  Ec2InstanceProfile:
    Type: AWS::IAM::InstanceProfile
    Properties:
      Roles:
        - !Ref Ec2Role

  # Application Load Balancer
  ApplicationLoadBalancer:
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
    Properties:
      Name: !Sub ${EnvironmentName}-alb
      Scheme: internet-facing
      SecurityGroups:
        - !Ref AlbSecurityGroup
      Subnets:
        - !Ref PublicSubnet1
        - !Ref PublicSubnet2
      Type: application

  ApplicationTargetGroup:
    Type: AWS::ElasticLoadBalancingV2::TargetGroup
    Properties:
      Name: !Sub ${EnvironmentName}-tg
      Port: 80
      Protocol: HTTP
      VpcId: !Ref VPC
      TargetType: instance
      HealthCheckPath: /health
      HealthCheckIntervalSeconds: 30
      HealthCheckTimeoutSeconds: 5
      HealthyThresholdCount: 2
      UnhealthyThresholdCount: 3
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-tg

  ApplicationListener:
    Type: AWS::ElasticLoadBalancingV2::Listener
    Properties:
      DefaultActions:
        - Type: forward
          TargetGroupArn: !Ref ApplicationTargetGroup
      LoadBalancerArn: !Ref ApplicationLoadBalancer
      Port: 80
      Protocol: HTTP

  # EC2 Instance
  Ec2Instance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !Ref LatestAmiId
      InstanceType: !Ref InstanceType
      IamInstanceProfile: !Ref Ec2InstanceProfile
      SecurityGroupIds:
        - !Ref InstanceSecurityGroup
      SubnetId: !Ref PublicSubnet1
      UserData:
        Fn::Base64: |
          #!/bin/bash
          yum update -y
          yum install -y httpd
          systemctl start httpd
          systemctl enable httpd
          echo "<h1>Hello from $(hostname)</h1>" > /var/www/html/index.html
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-instance
        - Key: Environment
          Value: !Ref EnvironmentName

Outputs:
  InstanceId:
    Description: EC2 Instance ID
    Value: !Ref Ec2Instance

  InstancePublicIp:
    Description: EC2 Instance Public IP
    Value: !GetAtt Ec2Instance.PublicIp

  LoadBalancerDnsName:
    Description: ALB DNS Name
    Value: !GetAtt ApplicationLoadBalancer.DNSName

  TargetGroupArn:
    Description: Target Group ARN
    Value: !Ref ApplicationTargetGroup

  SecurityGroupId:
    Description: Instance Security Group ID
    Value: !Ref InstanceSecurityGroup

  RoleArn:
    Description: IAM Role ARN
    Value: !GetAtt Ec2Role.Arn

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

  InstanceType:
    Type: AWS::EC2::InstanceType
    Description: EC2 instance type

  KeyName:
    Type: AWS::EC2::KeyPair::KeyName
    Description: Select a key pair
始终使用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

  InstanceType:
    Type: AWS::EC2::InstanceType
    Description: EC2 instance type

  KeyName:
    Type: AWS::EC2::KeyPair::KeyName
    Description: Select a key pair

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
AWSTemplateFormatVersion: 2010-09-09 Description: Network infrastructure (VPC, subnets, routes) Resources: VPC: AWS::EC2::VPC Subnets: AWS::EC2::Subnet

Security stack - changes occasionally

Security stack - changes occasionally

AWSTemplateFormatVersion: 2010-09-09 Description: Security resources (IAM roles, security groups) Resources: SecurityGroups: AWS::EC2::SecurityGroup Roles: AWS::IAM::Role
AWSTemplateFormatVersion: 2010-09-09 Description: Security resources (IAM roles, security groups) Resources: SecurityGroups: AWS::EC2::SecurityGroup Roles: AWS::IAM::Role

Application stack - changes frequently

Application stack - changes frequently

AWSTemplateFormatVersion: 2010-09-09 Description: Application resources (EC2 instances, ALB) Parameters: NetworkStackName: Type: String SecurityStackName: Type: String Resources: Instances: AWS::EC2::Instance LoadBalancer: AWS::ElasticLoadBalancingV2::LoadBalancer
undefined
AWSTemplateFormatVersion: 2010-09-09 Description: Application resources (EC2 instances, ALB) Parameters: NetworkStackName: Type: String SecurityStackName: Type: String Resources: Instances: AWS::EC2::Instance LoadBalancer: AWS::ElasticLoadBalancingV2::LoadBalancer
undefined

Use Meaningful Names

使用有意义的名称

Use
AWS::StackName
and parameters for consistent naming.
yaml
Resources:
  Ec2Instance:
    Type: AWS::EC2::Instance
    Properties:
      Tags:
        - Key: Name
          Value: !Sub ${AWS::StackName}-instance
        - Key: Environment
          Value: !Ref EnvironmentName
使用
AWS::StackName
和参数来实现一致的命名。
yaml
Resources:
  Ec2Instance:
    Type: AWS::EC2::Instance
    Properties:
      Tags:
        - Key: Name
          Value: !Sub ${AWS::StackName}-instance
        - 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}

  Ec2Instance:
    Type: AWS::EC2::Instance
    Properties:
      Tags:
        - Key: StackName
          Value: !Ref AWS::StackName
        - Key: Region
          Value: !Ref AWS::Region
使用伪参数来创建与区域无关的模板。
yaml
Resources:
  S3Bucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Sub ${AWS::StackName}-${AWS::AccountId}-${AWS::Region}

  Ec2Instance:
    Type: AWS::EC2::Instance
    Properties:
      Tags:
        - Key: StackName
          Value: !Ref AWS::StackName
        - Key: Region
          Value: !Ref AWS::Region

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 protect stack resources from unintended updates that could cause service disruption. Apply policies to prevent accidental modifications or deletions of critical resources.
yaml
Resources:
  # EC2 instance - allow updates but prevent deletion
  Ec2Instance:
    Type: AWS::EC2::Instance
    DeletionPolicy: Retain
    UpdateReplacePolicy: Retain

  # Database - prevent all updates
  DatabaseInstance:
    Type: AWS::RDS::DBInstance
    DeletionPolicy: Snapshot
    UpdateReplacePolicy: Retain
Stack Policy JSON Example:
json
{
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "Update:*",
      "Principal": "*",
      "Resource": "*"
    },
    {
      "Effect": "Deny",
      "Action": ["Update:Delete", "Update:Replace"],
      "Principal": "*",
      "Resource": "LogicalId=Ec2Instance"
    },
    {
      "Effect": "Deny",
      "Action": "Update:*",
      "Principal": "*",
      "Resource": "LogicalId=DatabaseInstance"
    }
  ]
}
Apply Stack Policy:
bash
aws cloudformation set-stack-policy \
  --stack-name my-ec2-stack \
  --stack-policy-body file://stack-policy.json
栈策略可以保护栈资源免受可能导致服务中断的意外更新。应用策略以防止对关键资源的意外修改或删除。
yaml
Resources:
  # EC2 instance - allow updates but prevent deletion
  Ec2Instance:
    Type: AWS::EC2::Instance
    DeletionPolicy: Retain
    UpdateReplacePolicy: Retain

  # Database - prevent all updates
  DatabaseInstance:
    Type: AWS::RDS::DBInstance
    DeletionPolicy: Snapshot
    UpdateReplacePolicy: Retain
栈策略JSON示例:
json
{
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "Update:*",
      "Principal": "*",
      "Resource": "*"
    },
    {
      "Effect": "Deny",
      "Action": ["Update:Delete", "Update:Replace"],
      "Principal": "*",
      "Resource": "LogicalId=Ec2Instance"
    },
    {
      "Effect": "Deny",
      "Action": "Update:*",
      "Principal": "*",
      "Resource": "LogicalId=DatabaseInstance"
    }
  ]
}
应用栈策略:
bash
aws cloudformation set-stack-policy \
  --stack-name my-ec2-stack \
  --stack-policy-body file://stack-policy.json

Or from a file

Or from a file

aws cloudformation set-stack-policy
--stack-name my-ec2-stack
--stack-policy-url https://s3.amazonaws.com/bucket/policy.json
undefined
aws cloudformation set-stack-policy
--stack-name my-ec2-stack
--stack-policy-url https://s3.amazonaws.com/bucket/policy.json
undefined

Termination Protection

终止保护

Enable termination protection to prevent accidental deletion of production stacks. This is critical for production environments.
bash
undefined
启用终止保护以防止意外删除生产栈。这对于生产环境至关重要。
bash
undefined

Enable termination protection when creating a stack

Enable termination protection when creating a stack

aws cloudformation create-stack
--stack-name my-ec2-stack
--template-body file://template.yaml
--enable-termination-protection
aws cloudformation create-stack
--stack-name my-ec2-stack
--template-body file://template.yaml
--enable-termination-protection

Enable termination protection on existing stack

Enable termination protection on existing stack

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

Disable termination protection (use with caution)

Disable termination protection (use with caution)

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

Check if termination protection is enabled

Check if termination protection is enabled

aws cloudformation describe-stacks
--stack-name my-ec2-stack
--query 'Stacks[0].EnableTerminationProtection'

**Best Practices for Termination Protection:**

- Enable on all production stacks
- Use AWS Organizations SCP to enforce termination protection
- Review before deleting development stacks
- Document the process for emergency termination
aws cloudformation describe-stacks
--stack-name my-ec2-stack
--query 'Stacks[0].EnableTerminationProtection'

**终止保护最佳实践:**

- 在所有生产栈上启用
- 使用AWS Organizations SCP来强制实施终止保护
- 删除开发栈前进行审查
- 记录紧急终止的流程

Drift Detection

漂移检测

Drift detection identifies differences between the actual infrastructure and the CloudFormation template. Regular drift checks ensure compliance and security.
bash
undefined
漂移检测可以识别实际基础设施与CloudFormation模板之间的差异。定期进行漂移检查可确保合规性和安全性。
bash
undefined

Detect drift on a stack

Detect drift on a stack

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

Get drift detection status

Get drift detection status

aws cloudformation describe-stack-drift-detection-status
--stack-drift-detection-id abc123
aws cloudformation describe-stack-drift-detection-status
--stack-drift-detection-id abc123

Get resources that have drifted

Get resources that have drifted

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

Get detailed drift information for a specific resource

Get detailed drift information for a specific resource

aws cloudformation describe-stack-resource-drifts
--stack-name my-ec2-stack
--stack-resource-drifts-limit 10

**Detect Drift Programmatically:**

```bash
#!/bin/bash
aws cloudformation describe-stack-resource-drifts
--stack-name my-ec2-stack
--stack-resource-drifts-limit 10

**程序化检测漂移:**

```bash
#!/bin/bash

detect-drift.sh - Automated drift detection script

detect-drift.sh - Automated drift detection script

STACK_NAME=$1 if [ -z "$STACK_NAME" ]; then echo "Usage: $0 <stack-name>" exit 1 fi
echo "Detecting drift for stack: $STACK_NAME"
STACK_NAME=$1 if [ -z "$STACK_NAME" ]; then echo "Usage: $0 <stack-name>" exit 1 fi
echo "Detecting drift for stack: $STACK_NAME"

Start drift detection

Start drift detection

DETECTION_ID=$(aws cloudformation detect-drift
--stack-name $STACK_NAME
--query 'StackId'
--output text)
echo "Drift detection started: $DETECTION_ID"
DETECTION_ID=$(aws cloudformation detect-drift
--stack-name $STACK_NAME
--query 'StackId'
--output text)
echo "Drift detection started: $DETECTION_ID"

Wait for drift detection to complete

Wait for drift detection to complete

STATUS="DETECTION_IN_PROGRESS" while [ "$STATUS" = "DETECTION_IN_PROGRESS" ]; do sleep 5 STATUS=$(aws cloudformation describe-stack-drift-detection-status
--stack-drift-detection-id $DETECTION_ID
--query 'DetectionStatus'
--output text) echo "Status: $STATUS" done
STATUS="DETECTION_IN_PROGRESS" while [ "$STATUS" = "DETECTION_IN_PROGRESS" ]; do sleep 5 STATUS=$(aws cloudformation describe-stack-drift-detection-status
--stack-drift-detection-id $DETECTION_ID
--query 'DetectionStatus'
--output text) echo "Status: $STATUS" done

Get drift status

Get drift status

DRIFT_STATUS=$(aws cloudformation describe-stack-drift-detection-status
--stack-drift-detection-id $DETECTION_ID
--query 'DriftStatus'
--output text)
echo "Drift Status: $DRIFT_STATUS"
if [ "$DRIFT_STATUS" = "DRIFTED" ]; then echo "Resources with drift:" aws cloudformation describe-stack-resource-drifts
--stack-name $STACK_NAME
--query 'StackResourceDrifts[].{LogicalId:LogicalResourceId,Status:ResourceDriftStatus,Type:ResourceType}' else echo "No drift detected - stack is in sync with template" fi

**Common Drift Scenarios:**

| Drift Type | Description | Action Required |
|------------|-------------|-----------------|
| MODIFIED | Resource properties changed | Review and update template or revert changes |
| DELETED | Resource deleted outside CFN | Recreate via template or import |
| ADDED | Resource created outside CFN | Import to stack or delete manually |
DRIFT_STATUS=$(aws cloudformation describe-stack-drift-detection-status
--stack-drift-detection-id $DETECTION_ID
--query 'DriftStatus'
--output text)
echo "Drift Status: $DRIFT_STATUS"
if [ "$DRIFT_STATUS" = "DRIFTED" ]; then echo "Resources with drift:" aws cloudformation describe-stack-resource-drifts
--stack-name $STACK_NAME
--query 'StackResourceDrifts[].{LogicalId:LogicalResourceId,Status:ResourceDriftStatus,Type:ResourceType}' else echo "No drift detected - stack is in sync with template" fi

**常见漂移场景:**

| 漂移类型 | 描述 | 所需操作 |
|------------|-------------|-----------------|
| MODIFIED | 资源属性已更改 | 审查并更新模板或还原更改 |
| DELETED | 资源在CFN外部被删除 | 通过模板重新创建或导入 |
| ADDED | 资源在CFN外部被创建 | 导入到栈中或手动删除 |

Change Sets

变更集

Change sets preview the impact of stack changes before execution. Always review change sets in production environments.
bash
undefined
变更集可以在执行前预览栈变更的影响。在生产环境中始终要审查变更集。
bash
undefined

Create a change set

Create a change set

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

List change sets for a stack

List change sets for a stack

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

Describe a change set to see the planned changes

Describe a change set to see the planned changes

aws cloudformation describe-change-set
--stack-name my-ec2-stack
--change-set-name my-ec2-changeset
aws cloudformation describe-change-set
--stack-name my-ec2-stack
--change-set-name my-ec2-changeset

Execute a change set

Execute a change set

aws cloudformation execute-change-set
--stack-name my-ec2-stack
--change-set-name my-ec2-changeset
aws cloudformation execute-change-set
--stack-name my-ec2-stack
--change-set-name my-ec2-changeset

Delete a change set if changes are not needed

Delete a change set if changes are not needed

aws cloudformation delete-change-set
--stack-name my-ec2-stack
--change-set-name my-ec2-changeset

**Change Set Types:**

| Type | Description | Use Case |
|------|-------------|----------|
| UPDATE | Preview changes to existing stack | Modifying existing resources |
| CREATE | Preview new stack creation | Creating new stacks from template |
| IMPORT | Preview resources to import | Importing existing resources |

**Review Change Sets with Filters:**

```bash
aws cloudformation delete-change-set
--stack-name my-ec2-stack
--change-set-name my-ec2-changeset

**变更集类型:**

| 类型 | 描述 | 使用场景 |
|------|-------------|----------|
| UPDATE | 预览对现有栈的变更 | 修改现有资源 |
| CREATE | 预览新栈的创建 | 从模板创建新栈 |
| IMPORT | 预览要导入的资源 | 导入现有资源 |

**使用过滤器审查变更集:**

```bash

Get changes affecting specific resource types

Get changes affecting specific resource types

aws cloudformation describe-change-set
--stack-name my-ec2-stack
--change-set-name my-ec2-changeset
--query 'Changes[?ResourceChange.ResourceType==
AWS::EC2::Instance
]'
aws cloudformation describe-change-set
--stack-name my-ec2-stack
--change-set-name my-ec2-changeset
--query 'Changes[?ResourceChange.ResourceType==
AWS::EC2::Instance
]'

Get changes with replacement impact

Get changes with replacement impact

aws cloudformation describe-change-set
--stack-name my-ec2-stack
--change-set-name my-ec2-changeset
--query 'Changes[?ResourceChange.Replacement!=
None
]'

**Automated Change Set Review Script:**

```bash
#!/bin/bash
aws cloudformation describe-change-set
--stack-name my-ec2-stack
--change-set-name my-ec2-changeset
--query 'Changes[?ResourceChange.Replacement!=
None
]'

**自动化变更集审查脚本:**

```bash
#!/bin/bash

review-changeset.sh - Automated change set review

review-changeset.sh - Automated change set review

STACK_NAME=$1 CHANGE_SET_NAME=$2 AUTO_APPROVE=false
while getopts "a" opt; do case $opt in a) AUTO_APPROVE=true ;; *) echo "Usage: $0 [-a] <stack-name> <change-set-name>" echo " -a: Auto-approve if no critical changes" exit 1 ;; esac done
echo "Reviewing change set: $CHANGE_SET_NAME" echo "Stack: $STACK_NAME" echo ""
STACK_NAME=$1 CHANGE_SET_NAME=$2 AUTO_APPROVE=false
while getopts "a" opt; do case $opt in a) AUTO_APPROVE=true ;; *) echo "Usage: $0 [-a] <stack-name> <change-set-name>" echo " -a: Auto-approve if no critical changes" exit 1 ;; esac done
echo "Reviewing change set: $CHANGE_SET_NAME" echo "Stack: $STACK_NAME" echo ""

Get change set summary

Get change set summary

CHANGES=$(aws cloudformation describe-change-set
--stack-name $STACK_NAME
--change-set-name $CHANGE_SET_NAME
--query 'Changes[*].{Type:Type,Resource:ResourceChange.LogicalResourceId,Action:ResourceChange.Action,Replacement:ResourceChange.Replacement}'
--output table)
echo "Planned Changes:" echo "$CHANGES" echo ""
CHANGES=$(aws cloudformation describe-change-set
--stack-name $STACK_NAME
--change-set-name $CHANGE_SET_NAME
--query 'Changes[*].{Type:Type,Resource:ResourceChange.LogicalResourceId,Action:ResourceChange.Action,Replacement:ResourceChange.Replacement}'
--output table)
echo "Planned Changes:" echo "$CHANGES" echo ""

Check for critical changes (replacements or deletions)

Check for critical changes (replacements or deletions)

CRITICAL_CHANGES=$(aws cloudformation describe-change-set
--stack-name $STACK_NAME
--change-set-name $CHANGE_SET_NAME
--query 'Changes[?ResourceChange.Replacement==
True
|| ResourceChange.Action==
Remove
]'
--output json)
if [ -n "$CRITICAL_CHANGES" ] && [ "$CRITICAL_CHANGES" != "[]" ]; then echo "WARNING: Critical changes detected that require manual review:" echo "$CRITICAL_CHANGES" echo "" echo "Please review manually before executing." exit 1 fi
if [ "$AUTO_APPROVE" = true ]; then echo "No critical changes - auto-executing change set..." aws cloudformation execute-change-set
--stack-name $STACK_NAME
--change-set-name $CHANGE_SET_NAME echo "Change set executed successfully." else echo "Review complete. No critical changes detected." echo "To execute: aws cloudformation execute-change-set --stack-name $STACK_NAME --change-set-name $CHANGE_SET_NAME" fi
undefined
CRITICAL_CHANGES=$(aws cloudformation describe-change-set
--stack-name $STACK_NAME
--change-set-name $CHANGE_SET_NAME
--query 'Changes[?ResourceChange.Replacement==
True
|| ResourceChange.Action==
Remove
]'
--output json)
if [ -n "$CRITICAL_CHANGES" ] && [ "$CRITICAL_CHANGES" != "[]" ]; then echo "WARNING: Critical changes detected that require manual review:" echo "$CRITICAL_CHANGES" echo "" echo "Please review manually before executing." exit 1 fi
if [ "$AUTO_APPROVE" = true ]; then echo "No critical changes - auto-executing change set..." aws cloudformation execute-change-set
--stack-name $STACK_NAME
--change-set-name $CHANGE_SET_NAME echo "Change set executed successfully." else echo "Review complete. No critical changes detected." echo "To execute: aws cloudformation execute-change-set --stack-name $STACK_NAME --change-set-name $CHANGE_SET_NAME" fi
undefined

Related Resources

相关资源