关于 terraform-stacks
Terraform Stacks 技能介绍如何用高层配置编排跨环境、区域和云账户的 Terraform 组件与部署,面向管理规模化基础设施的团队。内容涵盖专用 HCL 配置、Stacks CLI 部署流程及 HCP Terraform API 监控。
主要功能
- 01组合模块为组件与 Stack
- 02按环境、区域和账户定义部署
- 03使用 OIDC 工作负载身份认证
- 04通过 Stacks CLI 管理配置与部署
- 05借助 HCP Terraform API 监控运行
适用场景
- 01将基础设施模块编排到多个环境
- 02跨区域或云账户部署组件
- 03在自动化流程中监控部署状态
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ hashicorp/ agent-skills --skill terraform-stacks安装后在 Claude Code 中输入/terraform-stacks确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/api-monitoring.mdcomponent-blocks.mddeployment-blocks.mdexamples.mdlinked-stacks.mdtroubleshooting.md详细介绍
Terraform Stacks
Terraform Stacks 在传统 Terraform 模块之上提供配置层,简化大规模基础设施的预配和管理。Stacks 支持以声明式方式跨环境、区域和云账户编排多个组件。
核心概念
Stack:由组件和部署组成的完整基础设施单元,可统一管理。
组件:Terraform 模块的抽象,用于定义基础设施组成部分。每个组件都指定源模块、输入和提供程序。
部署:Stack 中所有组件的一个实例,并具有特定的输入值。可使用部署来配置不同的环境(dev/staging/prod)、区域或云账户。
Stack 语言:一种独立的、基于 HCL 的语言(不是常规 Terraform HCL),具有不同的块和文件扩展名。
文件结构
Terraform Stacks 使用特定的文件扩展名:
- 组件配置:
.tfcomponent.hcl - 部署配置:
.tfdeploy.hcl - 提供程序锁定文件:
.terraform.lock.hcl(由 CLI 生成)
所有配置文件都必须位于 Stack 仓库的根目录。HCP Terraform 会按依赖顺序处理所有文件。
推荐的文件组织方式
my-stack/
├── .terraform-version # The required Terraform version for this Stack
├── variables.tfcomponent.hcl # Variable declarations
├── providers.tfcomponent.hcl # Provider configurations
├── components.tfcomponent.hcl # Component definitions
├── outputs.tfcomponent.hcl # Stack outputs
├── deployments.tfdeploy.hcl # Deployment definitions
├── .terraform.lock.hcl # Provider lock file (generated)
└── modules/ # Local modules (optional - only if using local modules)
├── s3/
└── compute/
注意:仅在使用本地模块源时才需要 modules/ 目录。组件可以引用以下来源的模块:
- 本地文件路径:
./modules/vpc - 公共注册表:
terraform-aws-modules/vpc/aws - 私有注册表:
app.terraform.io/<org-name>/vpc/aws - Git:
git::https://github.com/org/repo.git//path?ref=v1.0.0
HCP Terraform 会按依赖顺序处理所有 .tfcomponent.hcl 和 .tfdeploy.hcl 文件。
所需的 Terraform 版本(.terraform-version)
使用 Terraform v1.13.x 或更高版本,以访问 Stacks CLI 插件并运行 terraform stacks CLI 命令。首先,在 Stack 的根目录中添加一个 .terraform-version 文件, 以指定 Stack 所需的 Terraform 版本。例如,以下文件指定 Terraform v1.14.5:
1.14.5
组件配置(.tfcomponent.hcl)
Variable 块
为 Stack 配置声明输入变量。变量必须定义 type 字段,且不支持 validation 参数。
variable "aws_region" {
type = string
description = "AWS region for deployments"
default = "us-west-1"
}
variable "identity_token" {
type = string
description = "OIDC identity token"
ephemeral = true # Does not persist to state file
}
variable "instance_count" {
type = number
nullable = false
}
重要:对凭据和令牌(身份令牌、API 密钥、密码)使用 ephemeral = true,以防止它们保留在状态文件中。对许可证密钥等需要跨运行保留的较长期值,请使用 stable。
Required Providers 块
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 6.0"
}
random = {
source = "hashicorp/random"
version = "~> 3.5.0"
}
}
Provider 块
Provider 块与传统 Terraform 中的不同:
- 支持
for_each元参数 - 在块头中定义别名(而不是将其作为参数)
- 通过
config块接受配置
单个 Provider 配置:
provider "aws" "this" {
config {
region = var.aws_region
assume_role_with_web_identity {
role_arn = var.role_arn
web_identity_token = var.identity_token
}
}
}
使用 for_each 配置多个 Provider:
provider "aws" "configurations" {
for_each = var.regions
config {
region = each.value
assume_role_with_web_identity {
role_arn = var.role_arn
web_identity_token = var.identity_token
}
}
}
身份验证最佳实践:对于 Stacks,优先使用 工作负载身份(OIDC)作为身份验证方法。这种方式可以:
- 避免使用长期静态凭据
- 为每次部署运行提供临时且范围受限的凭据
- 与云提供商 IAM 集成(AWS IAM 角色、Azure 托管标识、GCP 服务账号)
- 无需平台托管的环境变量
在 Provider 配置中使用 identity_token 块和 assume_role_with_web_identity 来配置工作负载身份。有关 AWS、Azure 和 GCP 的详细设置说明,请参阅:https://developer.hashicorp.com/terraform/cloud-docs/dynamic-provider-credentials
组件块
每个 Stack 至少需要一个组件块。为要包含在 Stack 中的每个模块添加一个组件。组件引用来自本地路径、注册表或 Git 的模块。
component "vpc" {
source = "app.terraform.io/my-org/vpc/aws" # Local, registry, or Git URL
version = "2.1.0" # For registry modules
inputs = {
cidr_block = var.vpc_cidr
name_prefix = var.name_prefix
}
providers = {
aws = provider.aws.this
}
}
有关依赖项、for_each、公共注册表模块、Git 源等示例,请参阅 references/component-blocks.md。
要点:
- 引用输出:
component.<name>.<output>;使用 for_each 时为component.<name>[key].<output> - 根据组件引用自动推断依赖关系
- 使用 for 表达式汇总:
[for x in component.s3 : x.bucket_name] - 对于带有
for_each的组件,引用特定实例:component.<name>[each.value].<output> - 提供程序引用是普通值:
provider.<type>.<alias>或provider.<type>.<alias>[each.value]
输出块
输出需要 type 参数,且不支持 preconditions:
output "vpc_id" {
type = string
description = "VPC ID"
value = component.vpc.vpc_id
}
output "endpoint_urls" {
type = map(string)
value = {
for region, comp in component.api : region => comp.endpoint_url
}
sensitive = false
}
Locals 块
Locals 块在 .tfcomponent.hcl 和 .tfdeploy.hcl 文件中的工作方式相同:
locals {
common_tags = {
Environment = var.environment
ManagedBy = "Terraform Stacks"
Project = var.project_name
}
region_config = {
for region in var.regions : region => {
name_suffix = "${var.environment}-${region}"
}
}
}
Removed 块
用于安全地从 Stack 中移除组件。HCP Terraform 需要组件的提供程序才能移除该组件。
removed {
from = component.old_component
source = "./modules/old-module"
providers = {
aws = provider.aws.this
}
}
部署配置(.tfdeploy.hcl)
身份令牌块
生成用于通过 OIDC 对云提供程序进行身份验证的 JWT 令牌:
identity_token "aws" {
audience = ["aws.workload.identity"]
}
identity_token "azure" {
audience = ["api://AzureADTokenExchange"]
}
在部署中使用 identity_token.<name>.jwt 引用令牌
Store 块
在 Stack 部署中访问 HCP Terraform 变量集:
store "varset" "aws_credentials" {
id = "varset-ABC123" # Alternatively use: name = "varset_name"
source = "tfc-cloud-shared"
category = "terraform" # Alternatively use: category = "env" for environment variables
}
deployment "production" {
inputs = {
aws_access_key = store.varset.aws_credentials.AWS_ACCESS_KEY_ID
}
}
用于集中管理凭证,并在各个 Stack 之间共享变量。详情请参阅 references/deployment-blocks.md。
部署块
定义部署实例(每个 Stack 最少 1 个,最多 20 个):
deployment "production" {
inputs = {
aws_region = "us-west-1"
instance_count = 3
role_arn = local.role_arn
identity_token = identity_token.aws.jwt
}
}
# Create multiple deployments for different environments
deployment "development" {
inputs = {
aws_region = "us-east-1"
instance_count = 1
name_suffix = "dev"
role_arn = local.role_arn
identity_token = identity_token.aws.jwt
}
}
销毁部署:设置 destroy = true,上传配置,批准销毁运行,然后移除部署块。详情请参阅 references/deployment-blocks.md。
部署组块
将部署归为一组,以共享设置(HCP Terraform Premium 层级功能)。免费版/标准版层级使用名为 {deployment-name}_default 的默认组。
deployment_group "canary" {
auto_approve_checks = [deployment_auto_approve.safe_changes]
}
deployment "dev" {
inputs = { /* ... */ }
deployment_group = deployment_group.canary
}
多个部署可以引用同一组。详情请参阅 references/deployment-blocks.md。
部署自动批准块
定义自动批准部署计划的规则(HCP Terraform Premium 层级功能):
deployment_auto_approve "safe_changes" {
deployment_group = deployment_group.canary
check {
condition = context.plan.changes.remove == 0
reason = "Cannot auto-approve plans with resource deletions"
}
}
可用的上下文变量:context.plan.applyable、context.plan.changes.add/change/remove/total、context.success
注意:orchestrate 块已弃用。请改用 deployment_group 和 deployment_auto_approve。
有关所有上下文变量和模式,请参阅 references/deployment-blocks.md。
发布输出和上游输入块
通过从一个 Stack 发布输出并在另一个 Stack 中使用这些输出来连接各个 Stack:
# In network Stack - publish outputs
publish_output "vpc_id_network" {
type = string
value = deployment.network.vpc_id
}
# In application Stack - consume outputs
upstream_input "network_stack" {
type = "stack"
source = "app.terraform.io/my-org/my-project/networking-stack"
}
deployment "app" {
inputs = {
vpc_id = upstream_input.network_stack.vpc_id_network
}
}
完整文档和示例请参阅 references/linked-stacks.md。
Terraform Stacks CLI
注意:Terraform CLI v1.13+ 起,Terraform Stacks 已正式发布(GA)。Stacks 现在会计入 HCP Terraform 账单中的受管理资源(RUM)。
初始化和验证
terraform stacks init # Download providers, modules, generate lock file
terraform stacks providers-lock # Regenerate lock file (add platforms if needed)
terraform stacks validate # Check syntax without uploading
部署工作流
重要提示:没有 plan 或 apply 命令。上传配置会自动触发部署运行。
# 1. Upload configuration (triggers deployment runs)
terraform stacks configuration upload
# 2. Monitor deployments
terraform stacks deployment-run list # List runs (non-interactive)
terraform stacks deployment-group watch -deployment-group=... # Stream status updates
# 3. Approve deployments (if auto-approve not configured)
terraform stacks deployment-run approve-all-plans -deployment-run-id=...
terraform stacks deployment-group approve-all-plans -deployment-group=...
terraform stacks deployment-run cancel -deployment-run-id=... # Cancel if needed
配置管理
terraform stacks configuration list # List configuration versions
terraform stacks configuration fetch -configuration-id=... # Download configuration
terraform stacks configuration watch # Monitor upload status
其他命令
terraform stacks create # Create new Stack (interactive)
terraform stacks fmt # Format Stack files
terraform stacks list # Show all Stacks
terraform stacks version # Display version
terraform stacks deployment-group rerun -deployment-group=... # Rerun deployment
使用 HCP Terraform API 监控部署
如需在自动化、CI/CD 或非交互式环境(例如 AI Agent)中进行程序化监控,请使用 HCP Terraform API,而不是 CLI 监控命令。该 API 提供以下端点:
- 配置状态和验证
- 部署组摘要
- 部署运行状态
- 部署步骤详情(plan/apply)
- 包含文件位置和代码片段的错误诊断信息
- 通过 artifacts 端点获取 Stack 输出
要点:
- CLI 监控命令会持续输出,不适用于自动化场景
- 使用 artifacts 端点获取 Stack 输出:
GET /api/v2/stack-deployment-steps/{step-id}/artifacts?name=apply-description - Diagnostics 端点需要
stack_deployment_step_id查询参数 - Artifacts 端点会返回 HTTP 307 重定向(使用
curl -L)
如需了解完整的 API 工作流、身份验证、轮询最佳实践和示例脚本,请参阅 references/api-monitoring.md。
常见模式
组件依赖关系:当一个组件引用另一个组件的输出时,会自动推断依赖关系(例如,subnet_ids = component.vpc.private_subnet_ids)。
多区域部署:在 providers 和组件上使用 for_each,即可跨多个区域部署。每个区域都有自己的 provider 配置和组件实例。
延迟变更:Stacks 支持延迟变更,以处理值只有在 apply 后才会确定的依赖关系。这使得复杂的多组件部署成为可能,其中某些资源依赖于其他组件在运行时生成的值(集群端点、生成的密码等)。
如需查看多区域部署、组件依赖关系、延迟变更模式和关联 Stacks 的完整示例,请参阅 references/examples.md。
最佳实践
- 组件粒度:为共享生命周期的逻辑基础设施单元创建组件
- 模块兼容性:
- 与 Stacks 配合使用的模块不能包含 provider 块(请在 Stack 配置中配置 providers)
- 在生产 Stacks 中使用前,先测试公共 Registry 模块——某些模块可能存在兼容性问题
- 如果无法确定模块的兼容性,可考虑为关键基础设施使用原始资源
- 示例:已发现某些版本的 terraform-aws-modules 与 Stacks 存在兼容性问题(例如 ALB 和 ECS 模块)
- 状态隔离:每个部署都有独立隔离的状态
- 输入变量:不同部署间有差异的值使用变量;共享值使用 locals
- Provider 锁定文件:始终生成
.terraform.lock.hcl并将其提交到版本控制系统 - 命名约定:为组件和部署使用描述性名称
- 部署组:可以将部署组织到部署组中。部署组支持自动批准规则、逻辑组织,并为扩展奠定基础。部署组是 HCP Terraform Premium 层级的一项功能
- 测试:在生产环境之前,先在开发/预发布部署中测试 Stack 配置
故障排查
循环依赖:重构以打破循环引用,或使用中间组件。
销毁部署:无法通过 UI 销毁。在部署块中设置 destroy = true,上传配置,HCP Terraform 随即会创建销毁运行。
诊断信息为空:在 diagnostics API 请求中添加必需的 stack_deployment_step_id 查询参数。
模块兼容性:在生产环境中使用前,先测试公共 Registry 模块。某些模块可能存在与 Stacks 的兼容性问题。
参考资料
如需详细文档,请参阅:
references/component-blocks.md- 完整的组件块参考,包含所有参数和语法references/deployment-blocks.md- 完整的部署块参考,包含所有配置选项references/linked-stacks.md- 发布输出和上游输入,以便将多个 Stack 链接在一起references/examples.md- 多区域和组件依赖关系的完整可运行示例references/api-monitoring.md- 用于程序化监控和自动化的完整 API 工作流references/troubleshooting.md- 常见问题及解决方案的详细故障排除指南