Terraform Stacks:MyCoCo 的 Landing Zone 依赖正确实现

发布: (2025年11月30日 GMT+8 06:23)
8 min read
原文: Dev.to

Source: Dev.to

电梯陈述

每个不断壮大的平台团队都会面临同样的架构挑战:共享基础设施——网络、安全、身份——必须独立于使用它的应用程序演进,但对这些 着陆区 的更改会不可预测地波及下游系统。MyCoCo 的平台团队在一次常规网络更新触发了 47 分钟的生产故障后深刻体会到了这一点。Terraform Stacks 现已在 HCP Terraform 中正式发布,它将着陆区管理从协同噩梦转变为自动编排的依赖图——让基础设施的变更安全、可见,并自动传播到每个使用它的应用程序。

TL;DR

  • 问题: 着陆区的更改(网络、安全、IAM 基线)会产生不可见的依赖,平台团队更新共享基础设施时会导致下游应用程序崩溃。
  • 解决方案: 使用带有 Linked Stacks 的 Terraform Stacks 正式化着陆区关系,在基础设施变更时自动触发下游计划。
  • 影响: MyCoCo 消除了因着陆区更新导致的意外宕机,并将跨团队协作从数小时的 Slack 信息缩减为自动的 HCP Terraform 通知。
  • 关键实现: 着陆区 Stack 通过 publish_output 块发布输出;产品 Stack 通过 upstream_input 块消费这些输出,并实现自动变更传播。
  • 结论: 如果你的平台团队管理被应用团队使用的共享基础设施,Linked Stacks 能将隐式依赖转化为显式、自动编排的关系。

挑战:着陆区更新导致一切崩溃

MyCoCo 的架构遵循了每个扩展中的平台团队都会采用的模式:由平台团队集中管理的着陆区,由产品团队通过 Terraform 数据源进行消费。五个产品团队、三个环境、两个区域——在纸面上看是清晰的关注点分离。实际操作中,却到处都是不可见的依赖。

突破点出现在一个星期五的下午。平台团队推送了一次例行的子网重组。GitHub Actions 成功运行。测试通过。三小时后,支持团队部署了一个引用已被重组的安全组 ID 的应用更新。生产环境宕机了 47 分钟。

“着陆区本应是稳定的基石,” Sam(高级 DevOps 工程师)说。“相反,它成了意外宕机的根源,因为我们根本不知道哪些产品 Stack 依赖哪些输出——直到出现故障。”

Jordan(平台工程师)自 beta 版起就一直在关注 Terraform Stacks。GA 版本加入了 Linked Stacks——正是 MyCoCo 所需要的:显式、可见且自动协调的着陆区依赖。

解决方案:用于着陆区架构的 Stacks

Terraform Stacks 通过三个相互关联的概念解决着陆区问题:

  1. Components(组件) – 可复用的基础设施定义。
  2. Deployments(部署) – 环境特定的实例化。
  3. Linked Stacks(关联 Stack) – 正式化跨 Stack 依赖。

重要提示: Stacks 仅是 HCP Terraform 的功能——在开源 Terraform 中不可用。采用基于 RUM 的计费模式时,每个受管资源都会计入账单。迁移前请明确建模成本,尤其是拥有众多下游消费者的大型着陆区。

Components:可复用的着陆区模块

Components 将 Terraform 模块包装成可复用的构建块。对于着陆区,这意味着只需一次定义网络、安全和身份组件:

# landing-zone/components.tfcomponent.hcl
component "vpc" {
  source = "./modules/vpc"

  inputs = {
    environment = var.environment
    cidr_block  = var.cidr_block
    region      = var.region
  }

  providers = {
    aws = provider.aws.main
  }
}

component "security_baseline" {
  source = "./modules/security"

  inputs = {
    vpc_id      = component.vpc.vpc_id
    environment = var.environment
  }

  providers = {
    aws = provider.aws.main
  }
}

Components 会自动解析内部依赖——security_baseline 会在 vpc 完成后才执行,无需编写编排脚本。

Deployments:保持环境一致性,避免漂移

Deployments 让你通过 Components 定义一次基础设施,然后在不同环境中只更改输入即可实例化:

# landing-zone/deployments.tfdeploy.hcl
deployment "development" {
  inputs = {
    environment = "dev"
    cidr_block  = "10.1.0.0/16"
    region      = "ca-central-1"
  }
}

deployment "production" {
  inputs = {
    environment = "prod"
    cidr_block  = "10.0.0.0/16"
    region      = "ca-central-1"
  }
}

两个部署运行完全相同的 VPC 和安全基线组件——只是使用了不同的输入。每个部署都有自己独立的状态文件,因而一个环境的更改永远不会意外影响另一个环境。

收益: 当平台团队更新 VPC 组件逻辑时,该更改会一致地推送到 dev 和 prod。再也不会出现“在 dev 正常,prod 崩溃”的情况,因为配置在数月的独立维护中已经漂移。

Linked Stacks:着陆区的游戏规则改变者

Linked Stacks 用显式、自动协调的关系取代了脆弱的数据源。

着陆区 Stack 为下游消费发布特定输出:

# landing-zone/deployments.tfdeploy.hcl (continued)
publish_output "vpc_id" {
  description = "Production VPC for application stacks"
  value       = deployment.production.vpc_id
}

publish_output "private_subnet_ids" {
  description = "Private subnets for application workloads"
  value       = deployment.production.private_subnet_ids
}

产品 Stack 使用 upstream_input 块声明对着陆区的显式依赖:

# product-stack/deployments.tfdeploy.hcl
upstream_input "landing_zone" {
  type   = "stack"
  source = "app.terraform.io/mycoco/platform/landing-zone"
}

deployment "production" {
  inputs = {
    environment = "prod"
    vpc_id      = upstream_input.landing_zone.vpc_id
    subnet_ids  = upstream_input.landing_zone.private_subnet_ids
  }
}

关键好处: 当平台团队更新着陆区——添加子网、修改安全组、变更路由——HCP Terraform 会自动触发所有下游产品 Stack 的计划。再也不需要“谁需要知道这次变更?”的讨论,也不再有因忘记依赖而导致的周五事故。

结果:无惧的着陆区变更

在将着陆区迁移到 Stacks 六周后,变化显而易见:

  • 着陆区更新从让人焦虑的 Slack 公告变成了常规操作。
  • 当需要进行网络更改时,HCP Terraform 会自动为所有五个产品 Stack 排队计划;产品团队可以准确看到是哪项上游变更触发了他们的运行。
  • 与着陆区漂移相关的事故频率在观察期间降至零。
  • 跨团队协作时间从数小时的手动沟通缩减为少量自动通知。

MyCoCo 现在将着陆区的演进视为一流、可观察的过程,而不是隐藏的风险,从而实现平台和产品工作负载的更快、更安全交付。

Back to Blog

相关文章

阅读更多 »

Terraform 项目:简单 EC2 + 安全组

项目结构 terraform-project/ │── main.tf │── variables.tf │── outputs.tf │── providers.tf │── terraform.tfvars │── modules/ │ └── ec2/ │ ├── main.tf │ …

在 S3 中保存 Terraform 状态

配置 S3 作为 Terraform 后端 Terraform 可以将其状态存储在 S3 存储桶中。以下是一个最小的配置示例,用于设置 S3 后端:hcl terrafor...