AWS 基础设施即代码深度对决:Terraform vs CloudFormation 全面对比与五大核心服务实战

📅 · 企业出海多云架构实战 - ChengziCloud

一句话结论

AWS 生态中,基础设施即代码(Infrastructure as Code,IaC)已经从"锦上添花"变成了"必备技能"。

本文要点
  • 引言:为什么 IaC 选型决定架构天花板
  • VPC 网络架构:谁更擅长编排复杂拓扑
  • IAM 权限管理:策略即代码的两种哲学
  • CloudWatch 监控与告警:可观测性即代码
  • AWS Organizations 多账号治理:IaC 的终极考验
  • 日常运维体验:状态管理、漂移检测与团队协作
  • 终极选型决策矩阵
  • 混合方案:两者并用是否可行?

引言:为什么 IaC 选型决定架构天花板

AWS 生态中,基础设施即代码(Infrastructure as Code,IaC)已经从"锦上添花"变成了"必备技能"。但在选型时,几乎所有团队都会卡在同一个问题上:Terraform 还是 CloudFormation?

这个问题看似简单,实则牵扯到 VPC 网络拓扑管理、IAM 权限边界定义、CloudWatch 监控配置、多账号组织架构部署等一系列连锁决策。选错了工具,不是写几行代码的事——是整个运维体系的重构成本。

本文不站队,不推货。我们从VPC 网络编排、IAM 策略管理、CloudWatch 可观测性、多账号 Organizations 治理、以及日常运维体验五个维度,逐一解剖两者的差异。每个维度都给出真实代码片段,让你看完就知道自己该选谁。

一个真实的选型困境

某跨境电商团队,AWS 上跑了三年,基础设施全部用 CloudFormation 管理。业务扩展到东南亚后开始用阿里云国际版做本地化部署。运维负责人面临两难:要么在阿里云手动管资源、要么引入 Terraform 统一编排。最终他们选择用 Terraform 管理跨云核心网络(VPC 互通、域名解析),保留 CloudFormation 管 AWS 应用层。这个"双轨制"运行了一年,结果是:运维脚本减少 60%,但团队学习曲线陡峭了三个月。

这个案例说明一个核心事实:IaC 工具的选择不是纯技术问题,而是团队能力、业务版图、现有资产三者权衡的结果。下面我们从五个维度展开这个权衡过程。


一、VPC 网络架构:谁更擅长编排复杂拓扑

1.1 CloudFormation 的 VPC 定义方式

CloudFormation 对 AWS 资源的覆盖是天级同步的——新服务发布当天就能用。定义 VPC 及其组件(子网、路由表、NAT 网关、Internet 网关)完全原生:


// CloudFormation YAML
Resources:
  MainVPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/16
      EnableDnsHostnames: true
      Tags:
        - Key: Name
          Value: MainVPC

  PublicSubnet:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref MainVPC
      CidrBlock: 10.0.1.0/24
      AvailabilityZone: !Select [0, !GetAZs ""]
      MapPublicIpOnLaunch: true

  InternetGateway:
    Type: AWS::EC2::InternetGateway

  AttachGateway:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId: !Ref MainVPC
      InternetGatewayId: !Ref InternetGateway

内建函数 !Ref、!GetAtt、!Select 让资源引用非常直观。但代价是:这段 YAML 只在 AWS 有效。如果你想同时管理阿里云 VPC,就得另起炉灶。

1.2 Terraform 的 VPC 定义方式

Terraform 用 HCL(HashiCorp Configuration Language)定义同样的 VPC:


// Terraform HCL
resource "aws_vpc" "main" {
  cidr_block           = "10.0.0.0/16"
  enable_dns_hostnames = true

  tags = {
    Name = "MainVPC"
  }
}

resource "aws_subnet" "public" {
  vpc_id                  = aws_vpc.main.id
  cidr_block              = "10.0.1.0/24"
  availability_zone       = data.aws_availability_zones.available.names[0]
  map_public_ip_on_launch = true
}

resource "aws_internet_gateway" "gw" {
  vpc_id = aws_vpc.main.id
}

Terraform 的资源引用用 aws_vpc.main.id 这种点号语法,比 YAML 的 !Ref 更接近编程语言习惯。更关键的是:Provider 体系让同一套语法能管理多云资源。

1.3 Transit Gateway 场景对比

场景CloudFormationTerraform
TGW + 多 VPC 挂载原生支持,AWS::EC2::TransitGateway + AWS::EC2::TransitGatewayAttachment同样原生,aws_ec2_transit_gateway + aws_ec2_transit_gateway_vpc_attachment
TGW 跨账号共享需配合 AWS RAM,CloudFormation StackSet 分发需配合 AWS RAM,Terraform aws_ram_* 资源 + 多 Provider 配置
TGW 路由表管理静态路由 + AWS::EC2::TransitGatewayRoute静态路由 + aws_ec2_transit_gateway_route,支持 for_each 批量路由
跨 Region TGW Peering需要在两个 Region 分别创建 Stack多 Provider alias 配置,一个 terraform apply 搞定

结论:单 Region、纯 AWS 环境,两者差异不大。跨 Region 或混合云场景,Terraform 的多 Provider 架构优势明显。


二、IAM 权限管理:策略即代码的两种哲学

2.1 CloudFormation 的 IAM 原生优势

CloudFormation 定义 IAM 角色和策略完全原生:


LambdaExecutionRole:
  Type: AWS::IAM::Role
  Properties:
    AssumeRolePolicyDocument:
      Version: "2012-10-17"
      Statement:
        - Effect: Allow
          Principal:
            Service: lambda.amazonaws.com
          Action: sts:AssumeRole
    ManagedPolicyArns:
      - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
    Policies:
      - PolicyName: S3Access
        PolicyDocument:
          Version: "2012-10-17"
          Statement:
            - Effect: Allow
              Action:
                - s3:GetObject
                - s3:PutObject
              Resource: !Sub "arn:aws:s3:::${BucketName}/*"

IAM 策略是 JSON 文档,CloudFormation 的 YAML 语法刚好与之天然兼容。

2.2 Terraform 的 IAM 定义方式

Terraform 有两种方式定义 IAM:

方式一:内联 JSON(与 CFn 类似)


resource "aws_iam_role" "lambda_role" {
  name = "lambda-execution-role"
  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [{
      Effect    = "Allow"
      Principal = { Service = "lambda.amazonaws.com" }
      Action    = "sts:AssumeRole"
    }]
  })
}

方式二:aws_iam_policy_document 数据源(推荐)


data "aws_iam_policy_document" "s3_access" {
  statement {
    effect = "Allow"
    actions = ["s3:GetObject", "s3:PutObject"]
    resources = ["${aws_s3_bucket.data.arn}/*"]
  }
}

resource "aws_iam_policy" "s3_access" {
  name   = "s3-access-policy"
  policy = data.aws_iam_policy_document.s3_access.json
}

2.3 IAM 管理对比

维度CloudFormationTerraform
IAM 策略语法原生 JSON/YAML,无学习成本jsonencode() 或 aws_iam_policy_document 数据源
权限边界(Permission Boundary)PermissionsBoundary 属性permissions_boundary 参数
SCP(Service Control Policy)无原生支持,需 Custom Resource 调用 Organizations APIaws_organizations_policy 资源
IAM Access Analyzer手动在控制台触发aws_accessanalyzer_analyzer 资源可 IaC 管理
策略模拟测试无 IaC 原生支持terraform plan 可预览变更,但不做策略语义校验

Terraform 的杀手锏:SCP 可以直接以资源形式管理,这对多账号 Organizations 治理至关重要。CloudFormation 要到 2023 年底才逐步补齐 Organizations 相关资源类型。


三、CloudWatch 监控与告警:可观测性即代码

3.1 CloudFormation 定义 CloudWatch


HighCPUAlarm:
  Type: AWS::CloudWatch::Alarm
  Properties:
    AlarmName: high-cpu-alarm
    AlarmDescription: CPU utilization exceeds 80%
    MetricName: CPUUtilization
    Namespace: AWS/EC2
    Statistic: Average
    Period: 300
    EvaluationPeriods: 2
    Threshold: 80
    ComparisonOperator: GreaterThanThreshold
    Dimensions:
      - Name: InstanceId
        Value: !Ref WebServer
    AlarmActions:
      - !Ref SNSTopic

配合 CloudFormation 的 AWS::CloudWatch::Dashboard 资源,你可以在一个 Stack 里同时定义资源和监控:


MainDashboard:
  Type: AWS::CloudWatch::Dashboard
  Properties:
    DashboardName: MainDashboard
    DashboardBody: !Sub |
      {
        "widgets": [
          {
            "type": "metric",
            "properties": {
              "metrics": [
                ["AWS/EC2", "CPUUtilization", {"stat": "Average"}]
              ],
              "period": 300,
              "title": "EC2 CPU"
            }
          }
        ]
      }

3.2 Terraform 定义 CloudWatch


resource "aws_cloudwatch_metric_alarm" "high_cpu" {
  alarm_name          = "high-cpu-alarm"
  comparison_operator = "GreaterThanThreshold"
  evaluation_periods  = 2
  metric_name         = "CPUUtilization"
  namespace           = "AWS/EC2"
  period              = 300
  statistic           = "Average"
  threshold           = 80
  dimensions = {
    InstanceId = aws_instance.web.id
  }
  alarm_actions = [aws_sns_topic.alerts.arn]
}

resource "aws_cloudwatch_dashboard" "main" {
  dashboard_name = "MainDashboard"
  dashboard_body = jsonencode({
    widgets = [{
      type = "metric"
      properties = {
        metrics = [["AWS/EC2", "CPUUtilization", { stat = "Average" }]]
        period  = 300
        title   = "EC2 CPU"
      }
    }]
  })
}

3.3 CloudWatch 管理对比

维度CloudFormationTerraform
告警定义原生 YAML,语法直观HCL + jsonencode(),Dashboard 定义较繁琐
复合告警(Composite Alarm)AWS::CloudWatch::CompositeAlarmaws_cloudwatch_composite_alarm
跨账号/跨 Region 告警需 StackSet 编排多 Provider 配置,天然支持
Logs Insights 查询无法通过 IaC 定义不支持定义查询语法,但可用 aws_cloudwatch_query_definition
Contributor InsightsCloudFormation 原生支持Terraform 也支持 aws_cloudwatch_contributor_insights_rule
ServiceLens / X-RayCloudFormation 不支持 X-Ray 组Terraform 有 aws_xray_group、aws_xray_sampling_rule

注意:CloudWatch Dashboard 的 JSON Body 在两种工具中都不好维护。生产环境建议用专门的监控即代码工具(如 Grafana Terraform Provider)来补充。


四、AWS Organizations 多账号治理:IaC 的终极考验

4.1 CloudFormation 的多账号方案:StackSets

CloudFormation 管理多账号的标准方案是 StackSets:


// 创建 StackSet,通过 Organizations 自动部署到所有成员账号
MyStackSet:
  Type: AWS::CloudFormation::StackSet
  Properties:
    StackSetName: SecurityBaseline
    PermissionModel: SERVICE_MANAGED
    AutoDeployment:
      Enabled: true
      RetainStacksOnAccountRemoval: false
    Capabilities:
      - CAPABILITY_IAM
      - CAPABILITY_NAMED_IAM
    ManagedExecution:
      Active: true
    Parameters:
      - ParameterKey: LogsRetentionDays
        ParameterValue: "90"
    TemplateURL: https://s3.amazonaws.com/bucket/security-baseline.yaml

StackSets 的优势是 AWS 原生集成,无需额外工具。劣势是:只支持 CloudFormation 模板,无法编排非 AWS 资源。

4.2 Terraform 的多账号方案:多 Provider + Workspace


// 定义多个 AWS Provider,指向不同账号
provider "aws" {
  alias  = "management"
  region = "us-east-1"
}

provider "aws" {
  alias  = "dev"
  region = "us-east-1"
  assume_role {
    role_arn = "arn:aws:iam::222222222222:role/OrganizationAccountAccessRole"
  }
}

provider "aws" {
  alias  = "prod"
  region = "us-east-1"
  assume_role {
    role_arn = "arn:aws:iam::333333333333:role/OrganizationAccountAccessRole"
  }
}

// 在 dev 账号创建 S3 桶
resource "aws_s3_bucket" "dev_data" {
  provider = aws.dev
  bucket   = "dev-data-bucket"
}

// 在 Organizations 管理账号创建 SCP
resource "aws_organizations_policy" "deny_public_s3" {
  provider = aws.management
  name     = "deny-public-s3"
  content = jsonencode({
    Version = "2012-10-17"
    Statement = [{
      Effect    = "Deny"
      Action    = ["s3:PutBucketPublicAccessBlock"]
      Resource  = ["*"]
      Condition = {
        StringNotEquals = {
          "s3:PublicAccessBlockConfiguration" : "true"
        }
      }
    }]
  })
}

4.3 Organizations 多账号对比

维度CloudFormation (StackSets)Terraform
部署模型推模式:管理账号推到成员账号拉模式:以成员账号身份执行
Organizations 集成SERVICE_MANAGED 权限模型,自动发现新账号需手动配置 Provider 或遍历 aws_organizations_organization 数据源
SCP 管理不支持直接创建 SCP(需 Lambda 自定义资源)aws_organizations_policy 资源,原生支持
OU 结构管理不支持直接创建 OUaws_organizations_organizational_unit 资源
Control Tower与 Control Tower 深度集成可以管理 Control Tower 创建的资源,但不触发 AFT
外部资源编排不支持同时管理 AWS + Datadog + PagerDuty + GitHub

关键发现:如果你只管理 AWS 资源且已用 Organizations + Control Tower,StackSets 更省心。如果需要跨云、需要管理 SCP/OU 结构本身、或团队已有 Terraform 经验,Terraform 是更好的选择。


五、日常运维体验:状态管理、漂移检测与团队协作

5.1 状态管理

特性CloudFormationTerraform
状态存储AWS 托管(无需自行管理)需自行管理(S3 + DynamoDB 锁,或 Terraform Cloud)
状态文件格式不可见(AWS 内部管理)JSON 明文,可审计可修复
状态锁定自动(Stack 级别)DynamoDB 或 Terraform Cloud
状态回滚ROLLBACK 模式自动回滚无自动回滚,需 terraform destroy + 重新 apply

5.2 漂移检测(Drift Detection)

CloudFormation 的漂移检测是 AWS 原生功能:


// 检测整个 Stack 的漂移
aws cloudformation detect-stack-drift --stack-name MainStack

// 查看漂移详情
aws cloudformation describe-stack-resource-drifts --stack-name MainStack

Terraform 的漂移检测本质上是 terraform plan:


terraform plan -detailed-exitcode
// 返回 0:无变更
// 返回 1:有错误
// 返回 2:有漂移(需要变更)
场景CloudFormationTerraform
漂移检测粒度资源级别,可逐个资源查询plan 输出所有差异
漂移修复需手动或重新部署 Stackterraform apply 自动修复
检测速度快(AWS 服务端计算)慢(本地计算,需调用 API)
第三方工具集成较弱丰富(Atlantis、Spacelift、Env0、Terrateam)

5.3 模块化与复用

CloudFormation 的模块化手段:

  • 嵌套 Stack:AWS::CloudFormation::Stack 资源引用外部模板
  • 模块(Module):2023 年推出,注册到 CloudFormation Registry
  • Include / Transform:AWS::Include 引用代码片段
  • 宏(Macros):Lambda 函数预处理模板

Terraform 的模块化手段:

  • Module:从 Terraform Registry 或 Git 仓库引用
  • for_each / count:原生循环,创建资源组
  • local / variable:丰富的变量体系
  • Provider 抽象:不同 Provider 共用同一套模块语法

// Terraform 模块示例:用 for_each 批量创建多个 VPC
module "vpcs" {
  source   = "terraform-aws-modules/vpc/aws"
  for_each = var.environments

  name = "vpc-${each.key}"
  cidr = each.value.cidr
  azs  = each.value.azs
}

CloudFormation 要达到同样的批量创建效果,需要在 YAML 里手动写多次,或用 Lambda 宏做模板预处理,复杂度明显更高。


六、终极选型决策矩阵

决策因子选 CloudFormation选 Terraform
技术栈纯 AWS,无多云需求多云 / 混合云
SCP / OU 管理不需要用 IaC 管 SCP需要用 IaC 管 SCP 和 OU 结构
团队技能团队熟悉 YAML/JSON团队需要编程式 DSL
状态管理不想管状态文件可以接受 S3 + DynamoDB 维护
Control Tower深度使用 Control TowerControl Tower 不是核心依赖
第三方集成不需要外部服务编排需同时编排 Datadog、PagerDuty 等
模块生态只有 AWS 模块Terraform Registry 有超过 4000 个 Provider
成本免费(AWS 服务不另收费)开源免费,Terraform Cloud 有付费版
CI/CD 集成CodePipeline 原生支持所有主流 CI/CD 平台支持(GitHub Actions、GitLab CI、Jenkins)

七、混合方案:两者并用是否可行?

答案是:可以,但需要明确边界。

一个越来越常见的模式是:

  • Terraform 管理"基础设施的基础":Organizations OU 结构、SCP、IAM Identity Center(原 AWS SSO)、VPC 骨架、Transit Gateway、Route53 托管区
  • CloudFormation 管理"应用层基础设施":Lambda 函数、API Gateway、ECS 服务、CloudWatch Dashboard(配合 Serverless Framework 或 AWS SAM)

// Terraform 创建核心 VPC,输出 VPC ID
output "main_vpc_id" {
  value = aws_vpc.main.id
}

// StackSets 引用 VPC ID,部署应用 Stack 到所有账号
// 参数从 Terraform 输出获取,通过 SSM Parameter Store 传递
resource "aws_ssm_parameter" "vpc_id" {
  name  = "/network/main-vpc-id"
  type  = "String"
  value = aws_vpc.main.id
}

这种分工的核心逻辑是:谁更擅长什么,就让它做什么。Terraform 强在多 Provider 编排和资源循环,CloudFormation 强在 AWS 原生集成和 StackSets 自动分发。


八、2026年最新趋势

  1. CloudFormation IaC Generator:从现有资源反向生成 CloudFormation 模板,迁移存量资源更方便
  2. Terraform Stacks(2024 年底 GA):HashiCorp 的多账号 / 多 Region 编排方案,直接对标 StackSets
  3. OpenTofu:Terraform 的开源分支,2025 年已支持 State Encryption 和 Provider 兼容性改进
  4. AWS CDK:用 TypeScript/Python 写 Infrastructure,编译成 CloudFormation 执行——IaC 的第三条路
  5. Platform Engineering 崛起:越来越多的团队用 Backstage + Terraform 搭建内部开发者平台

总结

Terraform 和 CloudFormation 没有绝对的优劣。如果你的架构圈定在 AWS 单一云、深度使用 Organizations + Control Tower,并且团队规模较小——CloudFormation + StackSets 可能更省心。如果你有跨云规划、需要管理 SCP/OU 本身、或者团队有较强的工程化需求——Terraform 是更灵活的选择。

最重要的是:选一个,然后深入用透。比工具选择更重要的是团队对 IaC 工程实践的成熟度——版本控制、代码审查、CI/CD 集成、漂移监控、成本标签——这些才是决定基础设施稳定性的真正变量。

本文由 7.chengzicloud.cloud 提供,点击访问首页了解更多