AWS CloudFormation 模板

FreeGuideOnline 最新 2026-07-13

什么是 AWS CloudFormation 模板

AWS CloudFormation 模板是一个声明式的 JSON 或 YAML 文件,用于描述你需要运行的 AWS 资源以及它们之间的配置关系。你只需编写一次模板,就可以在任意区域、账户中重复创建一致的资源栈,实现 基础设施即代码(IaC)。相较于手动点击控制台,模板能够避免操作失误、轻松复制环境并纳入版本控制。

简单理解:模板就是你云上架构的蓝图。

模板的基本结构

一个标准的 CloudFormation 模板由以下几个可选且功能明确的段组成。下面将以 YAML 格式为例(也支持 JSON)逐一说明。

---
AWSTemplateFormatVersion: "2010-09-09"
Description: >
    这里写模板的用途

Metadata:
  # 额外结构化信息

Parameters:
  # 用户输入参数

Mappings:
  # 静态查找表

Conditions:
  # 条件语句

Transform:
  # 宏或包含其他模板

Resources:
  # 核心:要创建的资源

Outputs:
  # 输出信息

AWSTemplateFormatVersion

声明模板格式版本,当前唯一有效值为 "2010-09-09"。该字段可选,但建议始终添加以确保兼容性。

AWSTemplateFormatVersion: "2010-09-09"

Description

一段纯文本描述,用于说明该模板的用途。如果文本较长,可以使用 > 折叠换行。

Description: >
  基于AWS最佳实践,
  部署带Nginx的EC2实例并配置安全组。  

Metadata

存放与模板相关的结构化额外信息,例如控制台界面分组显示参数、定义初始化时需要的文件等。初学者可暂不深入,但要知道这个段存在。

Parameters

允许用户在创建或更新栈时动态传入值,从而提高模板复用性。你可以定义类型、默认值、约束以及描述。

Parameters:
  InstanceType:
    Type: String
    Default: t3.micro
    AllowedValues:
      - t3.micro
      - t3.small
      - t3.medium
    Description: EC2 实例规格

Mappings

内置的静态查找表,常用于匹配区域、环境等条件下的固定值,比如不同区域的 AMI ID。

Mappings:
  RegionAMI:
    us-east-1:
      AMI: ami-0abcdef1234567890
    us-west-2:
      AMI: ami-0abcdef1234567891

Conditions

基于输入参数或环境信息,控制是否创建某些资源或设置属性。通常用于区分生产环境与测试环境。

Conditions:
  IsProduction: !Equals [!Ref EnvType, production]

Transform

指定模板处理宏,最常用的 AWS::Serverless 用于 SAM 应用,AWS::Include 可引用外部分段模板。基础模板中一般不需要。

Resources(核心)

唯一必选且最核心的段。在这里宣告所有需要创建的 AWS 资源,至少包含一个资源。每个资源声明都包括类型、属性和可选的依赖等。

Resources:
  MyEC2Instance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: ami-12345678
      InstanceType: t2.micro

支持的资源类型格式为 AWS::<服务名>::<资源类型>,你可以在 AWS 资源类型参考 中查找所有可用的资源。

Outputs

定义资源栈创建完成后,需要返回给用户或供其他栈使用的信息,例如实例的公网 IP、数据库端点等。输出的值可用于跨栈引用。

Outputs:
  WebsiteURL:
    Description: 实例的公网 DNS
    Value: !GetAtt MyEC2Instance.PublicDnsName

编写你的首个模板:启动一个可访问的 EC2 实例

接下来我们编写一个完整的模板,它将在默认 VPC 中创建一个安全组和一个 Amazon Linux 2 EC2 实例,并输出其公有 DNS。复制以下内容并保存为 first-stack.yaml,然后使用 CloudFormation 控制台或 CLI 上传部署。

---
AWSTemplateFormatVersion: "2010-09-09"
Description: 部署一个带安全组的 EC2 实例,开放 HTTP 访问

Parameters:
  InstanceType:
    Type: String
    Default: t3.micro
    AllowedValues: [t3.micro, t3.small]
    Description: 选择 EC2 实例规格

Mappings:
  RegionAMI:
    us-east-1:
      AMI: ami-0c02fb55956c7d316
    us-west-2:
      AMI: ami-0c55b159cbfafe1f0
    # 根据部署区域补充更多 AMI

Resources:
  # 安全组
  WebServerSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: 允许 HTTP 和 SSH 访问
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          CidrIp: 0.0.0.0/0
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: 0.0.0.0/0  # 生产环境中请限制此IP

  # EC2 实例
  WebServer:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !FindInMap [RegionAMI, !Ref "AWS::Region", AMI]
      InstanceType: !Ref InstanceType
      SecurityGroups:
        - !Ref WebServerSecurityGroup
      UserData:
        Fn::Base64: |
          #!/bin/bash
          yum update -y
          yum install -y httpd
          systemctl start httpd
          systemctl enable httpd
          echo "Hello from CloudFormation" > /var/www/html/index.html          

Outputs:
  WebsiteURL:
    Description: 实例的公网访问地址
    Value: !Sub "http://${WebServer.PublicDnsName}"
  • Parameters:运行时可以覆盖 InstanceType,增加灵活性。
  • Mappings + !FindInMap:根据部署的 AWS 区域自动选择正确的 AMI ID。
  • Resources:安全组放行 80 和 22 端口;实例引用安全组并使用 UserData 在启动时安装并启动 HTTP 服务。
  • Outputs:通过 !Sub 拼接出完整的访问 URL。

参数:让模板更灵活

参数是模板的输入接口,使同一个模板可以部署到不同场景。你需要掌握以下几点:

参数类型与约束

CloudFormation 提供了多种参数类型以满足不同需求:

类型 说明 示例
String 自由文本 "MyApp"
Number 整数或浮点数 3
List<Number> 数值列表 [80,443]
CommaDelimitedList 逗号分隔的字符串列表 "subnet-1,subnet-2"
AWS::EC2::VPC::Id 特定服务的资源类型,提供下拉和校验 自动列出账户内 VPC
AWS::SSM::Parameter::Value<String> 从 SSM Parameter Store 取值 便于统一管理参数

通过 AllowedValues, MinLength, MaxValue, ConstraintDescription 等可以进一步限制输入值,降低出错风险。

引用参数

使用内部函数 !Ref 引用参数值:

InstanceType: !Ref InstanceType

同样,!Ref 也可用于引用同一模板内其他资源,对于大多数资源会返回其物理 ID(如 i-1234567890abcdef0),对于 AWS::EC2::Instance 则返回实例 ID。

使用映射与条件

映射实战:根据环境与区域决定配置

结合 Mappings 可以轻松实现多环境、多区域的统一模板。例如根据环境(dev/prod)选取不同的实例规格:

Mappings:
  EnvConfig:
    dev:
      instanceType: t3.micro
    prod:
      instanceType: t3.large

# 在资源中引用
InstanceType: !FindInMap [EnvConfig, !Ref Environment, instanceType]

其中 Environment 是一个字符串参数,需要用户传入 devprod

条件:按需创建资源

条件允许某些资源或属性仅在满足特定表达式时才生效。以下示例只在环境为 prod 时创建 RDS 数据库:

Conditions:
  CreateDB: !Equals [!Ref Environment, prod]

Resources:
  MyDatabase:
    Condition: CreateDB
    Type: AWS::RDS::DBInstance
    Properties:
      Engine: mysql
      DBInstanceClass: db.t3.micro
      # 其他属性...

条件也可以用于控制属性的值,结合 !If 函数:

Properties:
  InstanceType: !If [IsProd, t3.large, t3.micro]

输出:导出关键信息

Outputs 不但用于向用户展示结果,还是 跨栈引用 的关键。导出的输出值可以被其他 CloudFormation 栈通过 Fn::ImportValue 导入,轻松实现分层架构。

Outputs:
  VPCId:
    Description: 新创建的 VPC ID
    Value: !Ref MyVPC
    Export:
      Name: !Sub "${AWS::StackName}-VPCId"

请注意,被导出的名称必须在同一区域唯一。建议使用 AWS::StackName 作为前缀以避免冲突。

最佳实践与进阶提示

  1. 始终使用参数化模板:避免硬编码 AMI ID、CIDR 块等,利用 Mappings 或 SSM 参数。
  2. 善用 AWS::NoValue:当条件不满足时,可移除某个属性而非将其设为空值,避免创建无效配置。
  3. 利用嵌套栈:将复杂架构拆分为多层、多个模板,通过 AWS::CloudFormation::Stack 资源引用,提高可维护性。
  4. 使用 cfn-lint 和 cfn-nag:在提交模板前进行静态分析,自动发现安全漏洞和语法错误。
  5. 保护敏感信息:切勿在模板中明文写入密码,应通过 NoEcho 参数配合 Secrets Manager 处理。
  6. 版本控制与变更集:将模板纳入 Git,部署前使用 变更集(Change Set) 预览影响,避免意外中断服务。
  7. 熟悉内部函数:掌握 !Ref, !Sub, !Join, !GetAtt, !FindInMap, !If, !Select 等函数,能让模板更简洁强大。

总结

AWS CloudFormation 模板是自动化管理 AWS 基础设施的基石。理解 ResourcesParametersMappingsOutputs 等核心段落,配合条件与内置函数,就能编写出健壮、可复用且易于维护的模板。从今天起,放弃手动操作,用代码定义你的云上世界。