mcpField
T
terraform-stacks

terraform-stacks

github.com/hashicorp云与 DevOps9095.6k 次安装今天更新
代码仓库

关于 terraform-stacks

Terraform Stacks 技能介绍如何用高层配置编排跨环境、区域和云账户的 Terraform 组件与部署,面向管理规模化基础设施的团队。内容涵盖专用 HCL 配置、Stacks CLI 部署流程及 HCP Terraform API 监控。

主要功能

  1. 01组合模块为组件与 Stack
  2. 02按环境、区域和账户定义部署
  3. 03使用 OIDC 工作负载身份认证
  4. 04通过 Stacks CLI 管理配置与部署
  5. 05借助 HCP Terraform API 监控运行

适用场景

  1. 01将基础设施模块编排到多个环境
  2. 02跨区域或云账户部署组件
  3. 03在自动化流程中监控部署状态

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/hashicorp/agent-skills --skill terraform-stacks

安装后在 Claude Code 中输入/terraform-stacks确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
api-monitoring.md
component-blocks.md
deployment-blocks.md
examples.md
linked-stacks.md
troubleshooting.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 中的不同:

  1. 支持 for_each 元参数
  2. 在块头中定义别名(而不是将其作为参数)
  3. 通过 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。

最佳实践

  1. 组件粒度:为共享生命周期的逻辑基础设施单元创建组件
  2. 模块兼容性:
    • 与 Stacks 配合使用的模块不能包含 provider 块(请在 Stack 配置中配置 providers)
    • 在生产 Stacks 中使用前,先测试公共 Registry 模块——某些模块可能存在兼容性问题
    • 如果无法确定模块的兼容性,可考虑为关键基础设施使用原始资源
    • 示例:已发现某些版本的 terraform-aws-modules 与 Stacks 存在兼容性问题(例如 ALB 和 ECS 模块)
  3. 状态隔离:每个部署都有独立隔离的状态
  4. 输入变量:不同部署间有差异的值使用变量;共享值使用 locals
  5. Provider 锁定文件:始终生成 .terraform.lock.hcl 并将其提交到版本控制系统
  6. 命名约定:为组件和部署使用描述性名称
  7. 部署组:可以将部署组织到部署组中。部署组支持自动批准规则、逻辑组织,并为扩展奠定基础。部署组是 HCP Terraform Premium 层级的一项功能
  8. 测试:在生产环境之前,先在开发/预发布部署中测试 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 - 常见问题及解决方案的详细故障排除指南

评论

支持 Markdown