Terraform Stacks:MyCoCo 的 Landing Zone 依赖正确实现
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 通过三个相互关联的概念解决着陆区问题:
- Components(组件) – 可复用的基础设施定义。
- Deployments(部署) – 环境特定的实例化。
- 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 现在将着陆区的演进视为一流、可观察的过程,而不是隐藏的风险,从而实现平台和产品工作负载的更快、更安全交付。