terraform-stacks

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Terraform Stacks

Terraform Stacks

Terraform Stacks simplify infrastructure provisioning and management at scale by providing a configuration layer above traditional Terraform modules. Stacks enable declarative orchestration of multiple components across environments, regions, and cloud accounts.
Terraform Stacks 通过在传统 Terraform 模块之上提供一个配置层,简化了大规模基础设施的供应与管理。栈支持跨环境、区域和云账户的多个组件的声明式编排。

Core Concepts

核心概念

Stack: A complete unit of infrastructure composed of components and deployments that can be managed together.
Component: An abstraction around a Terraform module that defines infrastructure pieces. Each component specifies a source module, inputs, and providers.
Deployment: An instance of all components in a stack with specific input values. Use deployments for different environments (dev/staging/prod), regions, or cloud accounts.
Stack Language: A separate HCL-based language (not regular Terraform HCL) with distinct blocks and file extensions.
Stack(栈):由组件和部署组成的完整基础设施单元,可进行统一管理。
Component(组件):围绕 Terraform 模块的抽象,定义基础设施片段。每个组件指定源模块、输入和提供程序。
Deployment(部署):栈中所有组件的实例,带有特定输入值。可针对不同环境(开发/预发布/生产)、区域或云账户创建部署。
Stack Language(栈语言):基于 HCL 的独立语言(非标准 Terraform HCL),具有独特的块和文件扩展名。

File Structure

文件结构

Terraform Stacks use specific file extensions:
  • Component configuration:
    .tfcomponent.hcl
  • Deployment configuration:
    .tfdeploy.hcl
  • Provider lock file:
    .terraform.lock.hcl
    (generated by CLI)
All configuration files must be at the root level of the Stack repository. HCP Terraform processes all files in dependency order.
Terraform Stacks 使用特定的文件扩展名:
  • 组件配置
    .tfcomponent.hcl
  • 部署配置
    .tfdeploy.hcl
  • 提供程序锁定文件
    .terraform.lock.hcl
    (由 CLI 生成)
所有配置文件必须位于栈仓库的根目录。HCP Terraform 会按依赖顺序处理所有文件。

Recommended File Organization

推荐文件组织方式

my-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)
    ├── vpc/
    └── compute/
Note: The
modules/
directory is only required when using local module sources. Components can reference modules from:
  • Local file paths:
    ./modules/vpc
  • Public registry:
    terraform-aws-modules/vpc/aws
  • Private registry:
    app.terraform.io/<org-name>/vpc/aws
When validating Stack configurations, check component source declarations rather than assuming a local
modules/
directory must exist.
my-stack/
├── variables.tfcomponent.hcl        # 变量声明
├── providers.tfcomponent.hcl        # 提供程序配置
├── components.tfcomponent.hcl       # 组件定义
├── outputs.tfcomponent.hcl          # 栈输出
├── deployments.tfdeploy.hcl         # 部署定义
├── .terraform.lock.hcl              # 提供程序锁定文件(生成的)
└── modules/                         # 本地模块(可选 - 仅当使用本地模块时需要)
    ├── vpc/
    └── compute/
注意:仅当使用本地模块源时才需要
modules/
目录。组件可以引用以下来源的模块:
  • 本地文件路径:
    ./modules/vpc
  • 公开注册表:
    terraform-aws-modules/vpc/aws
  • 私有注册表:
    app.terraform.io/<org-name>/vpc/aws
验证栈配置时,请检查组件源声明,不要默认认为必须存在本地
modules/
目录。

Component Configuration (.tfcomponent.hcl)

组件配置(.tfcomponent.hcl)

Variable Block

变量块

Declare input variables for the Stack configuration. Variables must define a
type
field and do not support the
validation
argument.
hcl
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
}
声明栈配置的输入变量。变量必须定义
type
字段,不支持
validation
参数。
hcl
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
}

Required Providers Block

必需提供程序块

Works the same as traditional Terraform configurations:
hcl
required_providers {
  aws = {
    source  = "hashicorp/aws"
    version = "~> 5.7.0"
  }
  random = {
    source  = "hashicorp/random"
    version = "~> 3.5.0"
  }
}
与传统 Terraform 配置的工作方式相同:
hcl
required_providers {
  aws = {
    source  = "hashicorp/aws"
    version = "~> 5.7.0"
  }
  random = {
    source  = "hashicorp/random"
    version = "~> 3.5.0"
  }
}

Provider Block

提供程序块

Provider blocks differ from traditional Terraform:
  1. Support
    for_each
    meta-argument
  2. Define aliases in the block header (not as an argument)
  3. Accept configuration through a
    config
    block
Single Provider Configuration:
hcl
provider "aws" "this" {
  config {
    region = var.aws_region
    assume_role_with_web_identity {
      role_arn           = var.role_arn
      web_identity_token = var.identity_token
    }
  }
}
Multiple Provider Configurations with for_each:
hcl
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
    }
  }
}
提供程序块与传统 Terraform 不同:
  1. 支持
    for_each
    元参数
  2. 在块头部定义别名(而非作为参数)
  3. 通过
    config
    块接受配置
单一提供程序配置:
hcl
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 的多提供程序配置:
hcl
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
    }
  }
}

Component Block

组件块

Each Stack requires at least one component block. Add a component for each module to include in the Stack.
Component Source: Each component's
source
argument must specify one of the following source types:
  • Local file path:
    ./modules/vpc
  • Public registry:
    terraform-aws-modules/vpc/aws
  • Private registry:
    app.terraform.io/my-org/vpc/aws
  • Git repository:
    git::https://github.com/org/repo.git//modules/vpc?ref=v1.0.0
hcl
component "vpc" {
  source = "./modules/vpc"

  inputs = {
    cidr_block  = var.vpc_cidr
    name_prefix = var.name_prefix
  }

  providers = {
    aws = provider.aws.this
  }
}

component "networking" {
  source  = "app.terraform.io/my-org/vpc/aws"
  version = "2.1.0"

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

  providers = {
    aws = provider.aws.this
  }
}

component "compute" {
  source = "./modules/compute"

  inputs = {
    vpc_id          = component.vpc.vpc_id
    subnet_ids      = component.vpc.private_subnet_ids
    instance_type   = var.instance_type
  }

  providers = {
    aws = provider.aws.this
  }
}
Component with for_each for Multi-Region:
hcl
component "s3" {
  for_each = var.regions
  
  source = "./modules/s3"
  
  inputs = {
    region = each.value
    tags   = var.common_tags
  }
  
  providers = {
    aws = provider.aws.configurations[each.value]
  }
}
Key Points:
  • Reference component outputs using
    component.<name>.<output>
  • All inputs are provided as a single
    inputs
    object
  • Provider references are normal values:
    provider.<type>.<alias>
  • Dependencies are automatically inferred from component references
每个栈至少需要一个组件块。为要包含在栈中的每个模块添加一个组件。
组件源:每个组件的
source
参数必须指定以下源类型之一:
  • 本地文件路径:
    ./modules/vpc
  • 公开注册表:
    terraform-aws-modules/vpc/aws
  • 私有注册表:
    app.terraform.io/my-org/vpc/aws
  • Git 仓库:
    git::https://github.com/org/repo.git//modules/vpc?ref=v1.0.0
hcl
component "vpc" {
  source = "./modules/vpc"

  inputs = {
    cidr_block  = var.vpc_cidr
    name_prefix = var.name_prefix
  }

  providers = {
    aws = provider.aws.this
  }
}

component "networking" {
  source  = "app.terraform.io/my-org/vpc/aws"
  version = "2.1.0"

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

  providers = {
    aws = provider.aws.this
  }
}

component "compute" {
  source = "./modules/compute"

  inputs = {
    vpc_id          = component.vpc.vpc_id
    subnet_ids      = component.vpc.private_subnet_ids
    instance_type   = var.instance_type
  }

  providers = {
    aws = provider.aws.this
  }
}
用于多区域的 for_each 组件:
hcl
component "s3" {
  for_each = var.regions
  
  source = "./modules/s3"
  
  inputs = {
    region = each.value
    tags   = var.common_tags
  }
  
  providers = {
    aws = provider.aws.configurations[each.value]
  }
}
关键点:
  • 使用
    component.<name>.<output>
    引用组件输出
  • 所有输入作为单个
    inputs
    对象提供
  • 提供程序引用为普通值:
    provider.<type>.<alias>
  • 依赖关系会自动从组件引用中推断

Output Block

输出块

Outputs require a
type
argument and do not support
preconditions
:
hcl
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
}
输出需要
type
参数,不支持
preconditions
hcl
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 Block

本地值块

Works exactly as in traditional Terraform:
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}"
    }
  }
}
与传统 Terraform 的工作方式完全相同:
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 Block

移除块

Use to safely remove components from a Stack. HCP Terraform requires the component's providers to remove it.
hcl
removed {
  from   = component.old_component
  source = "./modules/old-module"
  
  providers = {
    aws = provider.aws.this
  }
}
用于安全地从栈中移除组件。HCP Terraform 需要组件的提供程序才能将其移除。
hcl
removed {
  from   = component.old_component
  source = "./modules/old-module"
  
  providers = {
    aws = provider.aws.this
  }
}

Deployment Configuration (.tfdeploy.hcl)

部署配置(.tfdeploy.hcl)

Identity Token Block

身份令牌块

Generate JWT tokens for OIDC authentication with cloud providers:
hcl
identity_token "aws" {
  audience = ["aws.workload.identity"]
}

identity_token "azure" {
  audience = ["api://AzureADTokenExchange"]
}
Reference tokens in deployments using
identity_token.<name>.jwt
生成用于云提供商 OIDC 身份验证的 JWT 令牌:
hcl
identity_token "aws" {
  audience = ["aws.workload.identity"]
}

identity_token "azure" {
  audience = ["api://AzureADTokenExchange"]
}
使用
identity_token.<name>.jwt
在部署中引用令牌

Locals Block

本地值块

Define local values for deployment configuration:
hcl
locals {
  aws_regions = ["us-west-1", "us-east-1", "eu-west-1"]
  role_arn    = "arn:aws:iam::123456789012:role/hcp-terraform-stacks"
}
为部署配置定义本地值:
hcl
locals {
  aws_regions = ["us-west-1", "us-east-1", "eu-west-1"]
  role_arn    = "arn:aws:iam::123456789012:role/hcp-terraform-stacks"
}

Deployment Block

部署块

Define deployment instances. Each Stack requires at least one deployment (maximum 20 per Stack).
Single Environment Deployment:
hcl
deployment "production" {
  inputs = {
    aws_region     = "us-west-1"
    instance_count = 3
    role_arn       = local.role_arn
    identity_token = identity_token.aws.jwt
  }
}
Multiple Environment Deployments:
hcl
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
  }
}

deployment "staging" {
  inputs = {
    aws_region     = "us-east-1"
    instance_count = 2
    name_suffix    = "staging"
    role_arn       = local.role_arn
    identity_token = identity_token.aws.jwt
  }
}

deployment "production" {
  inputs = {
    aws_region     = "us-west-1"
    instance_count = 5
    name_suffix    = "prod"
    role_arn       = local.role_arn
    identity_token = identity_token.aws.jwt
  }
}
Destroying a Deployment:
To safely remove a deployment:
hcl
deployment "old_environment" {
  inputs = {
    aws_region     = "us-west-1"
    instance_count = 2
    role_arn       = local.role_arn
    identity_token = identity_token.aws.jwt
  }
  destroy = true  # Mark for destruction
}
After applying the plan and the deployment is destroyed, remove the deployment block from your configuration.
定义部署实例。每个栈至少需要一个部署(每个栈最多 20 个)。
单一环境部署:
hcl
deployment "production" {
  inputs = {
    aws_region     = "us-west-1"
    instance_count = 3
    role_arn       = local.role_arn
    identity_token = identity_token.aws.jwt
  }
}
多环境部署:
hcl
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
  }
}

deployment "staging" {
  inputs = {
    aws_region     = "us-east-1"
    instance_count = 2
    name_suffix    = "staging"
    role_arn       = local.role_arn
    identity_token = identity_token.aws.jwt
  }
}

deployment "production" {
  inputs = {
    aws_region     = "us-west-1"
    instance_count = 5
    name_suffix    = "prod"
    role_arn       = local.role_arn
    identity_token = identity_token.aws.jwt
  }
}
销毁部署:
要安全地移除部署:
hcl
deployment "old_environment" {
  inputs = {
    aws_region     = "us-west-1"
    instance_count = 2
    role_arn       = local.role_arn
    identity_token = identity_token.aws.jwt
  }
  destroy = true  # Mark for destruction
}
在应用计划并销毁部署后,从配置中移除该部署块。

Deployment Group Block

部署组块

Group deployments together to configure shared settings (Premium feature). Best Practice: Always create deployment groups for all deployments, even single deployments, to enable future auto-approval rules and maintain consistent configuration patterns.
hcl
deployment_group "canary" {
  deployments = [
    deployment.dev,
    deployment.staging
  ]
}

deployment_group "production" {
  deployments = [
    deployment.prod_us_east,
    deployment.prod_us_west
  ]
}
将部署分组以配置共享设置(高级功能)。最佳实践:始终为所有部署创建部署组,即使只有一个部署,以启用未来的自动批准规则并保持一致的配置模式。
hcl
deployment_group "canary" {
  deployments = [
    deployment.dev,
    deployment.staging
  ]
}

deployment_group "production" {
  deployments = [
    deployment.prod_us_east,
    deployment.prod_us_west
  ]
}

Deployment Auto-Approve Block

部署自动批准块

Define rules that automatically approve deployment plans based on specific conditions (Premium feature):
hcl
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"
  }
  
  check {
    condition = context.plan.applyable
    reason    = "Plan must be applyable"
  }
}

deployment_auto_approve "applyable_only" {
  deployment_group = deployment_group.production
  
  check {
    condition = context.plan.applyable
    reason    = "Plan must be successful"
  }
}
Available Context Variables:
  • context.plan.applyable
    - Plan succeeded without errors
  • context.plan.changes.add
    - Number of resources to add
  • context.plan.changes.change
    - Number of resources to change
  • context.plan.changes.remove
    - Number of resources to remove
Note:
orchestrate
blocks are deprecated. Use
deployment_group
and
deployment_auto_approve
instead.
定义基于特定条件自动批准部署计划的规则(高级功能):
hcl
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"
  }
  
  check {
    condition = context.plan.applyable
    reason    = "Plan must be applyable"
  }
}

deployment_auto_approve "applyable_only" {
  deployment_group = deployment_group.production
  
  check {
    condition = context.plan.applyable
    reason    = "Plan must be successful"
  }
}
可用上下文变量:
  • context.plan.applyable
    - 计划成功无错误
  • context.plan.changes.add
    - 要添加的资源数量
  • context.plan.changes.change
    - 要修改的资源数量
  • context.plan.changes.remove
    - 要删除的资源数量
注意
orchestrate
块已弃用。请改用
deployment_group
deployment_auto_approve

Publish Output Block

发布输出块

Export outputs from a Stack for use in other Stacks (linked Stacks):
hcl
publish_output "vpc_id_network" {
  type  = string
  value = deployment.network.vpc_id
}

publish_output "subnet_ids" {
  type  = list(string)
  value = deployment.network.private_subnet_ids
}
导出栈的输出以供其他栈(链接栈)使用:
hcl
publish_output "vpc_id_network" {
  type  = string
  value = deployment.network.vpc_id
}

publish_output "subnet_ids" {
  type  = list(string)
  value = deployment.network.private_subnet_ids
}

Upstream Input Block

上游输入块

Reference published outputs from another Stack:
hcl
upstream_input "network_stack" {
  type   = "stack"
  source = "app.terraform.io/my-org/my-project/networking-stack"
}

deployment "application" {
  inputs = {
    vpc_id     = upstream_input.network_stack.vpc_id_network
    subnet_ids = upstream_input.network_stack.subnet_ids
  }
}
引用另一个栈发布的输出:
hcl
upstream_input "network_stack" {
  type   = "stack"
  source = "app.terraform.io/my-org/my-project/networking-stack"
}

deployment "application" {
  inputs = {
    vpc_id     = upstream_input.network_stack.vpc_id_network
    subnet_ids = upstream_input.network_stack.subnet_ids
  }
}

Terraform Stacks CLI

Terraform Stacks CLI

Initialize and Validate

初始化与验证

Generate provider lock file:
bash
terraform stacks providers-lock
Validate Stack configuration:
bash
terraform stacks validate
生成提供程序锁定文件:
bash
terraform stacks providers-lock
验证栈配置:
bash
terraform stacks validate

Plan and Apply

计划与应用

Plan a specific deployment:
bash
terraform stacks plan --deployment=production
Apply a deployment:
bash
terraform stacks apply --deployment=production
为特定部署生成计划:
bash
terraform stacks plan --deployment=production
应用部署:
bash
terraform stacks apply --deployment=production

Common Patterns

常见模式

Multi-Region Deployment

多区域部署

hcl
undefined
hcl
undefined

variables.tfcomponent.hcl

variables.tfcomponent.hcl

variable "regions" { type = set(string) default = ["us-west-1", "us-east-1", "eu-west-1"] }
variable "regions" { type = set(string) default = ["us-west-1", "us-east-1", "eu-west-1"] }

providers.tfcomponent.hcl

providers.tfcomponent.hcl

provider "aws" "regional" { for_each = var.regions
config { region = each.value assume_role_with_web_identity { role_arn = var.role_arn web_identity_token = var.identity_token } } }
provider "aws" "regional" { for_each = var.regions
config { region = each.value assume_role_with_web_identity { role_arn = var.role_arn web_identity_token = var.identity_token } } }

components.tfcomponent.hcl

components.tfcomponent.hcl

component "regional_infra" { for_each = var.regions source = "./modules/regional"
inputs = { region = each.value }
providers = { aws = provider.aws.regional[each.value] } }
undefined
component "regional_infra" { for_each = var.regions source = "./modules/regional"
inputs = { region = each.value }
providers = { aws = provider.aws.regional[each.value] } }
undefined

Component Dependencies

组件依赖

Dependencies are automatically inferred when one component references another's output:
hcl
component "database" {
  source = "./modules/rds"
  
  inputs = {
    subnet_ids = component.vpc.private_subnet_ids  # Creates dependency
  }
  
  providers = {
    aws = provider.aws.this
  }
}
当一个组件引用另一个组件的输出时,依赖关系会自动推断:
hcl
component "database" {
  source = "./modules/rds"
  
  inputs = {
    subnet_ids = component.vpc.private_subnet_ids  # Creates dependency
  }
  
  providers = {
    aws = provider.aws.this
  }
}

Best Practices

最佳实践

  1. Component Granularity: Create components for logical infrastructure units that share a lifecycle
  2. Module Compatibility: Modules used with Stacks cannot include provider blocks (configure providers in Stack configuration)
  3. State Isolation: Each deployment has its own isolated state
  4. Input Variables: Use variables for values that differ across deployments; use locals for shared values
  5. Provider Lock Files: Always generate and commit
    .terraform.lock.hcl
    to version control
  6. Naming Conventions: Use descriptive names for components and deployments
  7. Deployment Groups: Always organize deployments into deployment groups, even if you only have one deployment. Deployment groups enable auto-approval rules, logical organization, and provide a foundation for scaling. While deployment groups are a Premium feature, organizing your configurations to use them is a best practice for all Stacks
  8. Testing: Test Stack configurations in dev/staging deployments before production
  1. 组件粒度:为具有相同生命周期的逻辑基础设施单元创建组件
  2. 模块兼容性:与栈一起使用的模块不能包含提供程序块(在栈配置中配置提供程序)
  3. 状态隔离:每个部署都有自己的隔离状态
  4. 输入变量:对跨部署不同的值使用变量;对共享值使用本地值
  5. 提供程序锁定文件:始终生成并提交
    .terraform.lock.hcl
    到版本控制
  6. 命名约定:为组件和部署使用描述性名称
  7. 部署组:始终将部署组织到部署组中,即使只有一个部署。部署组支持自动批准规则、逻辑组织,并为扩展提供基础。虽然部署组是高级功能,但组织配置以使用它们是所有栈的最佳实践
  8. 测试:在生产环境之前,在开发/预发布部署中测试栈配置

Troubleshooting

故障排除

Circular Dependencies

循环依赖

Issue: Component A references Component B, and Component B references Component A Solution: Refactor to break the circular reference or use intermediate components
问题:组件 A 引用组件 B,组件 B 引用组件 A 解决方案:重构以打破循环引用或使用中间组件

Deployment Limit

部署限制

HCP Terraform supports maximum 20 deployments per Stack. For more instances, use multiple Stacks or
for_each
within components.
HCP Terraform 每个栈最多支持 20 个部署。对于更多实例,请使用多个栈或在组件内使用
for_each

References

参考资料

For detailed block specifications and advanced features, see:
  • references/component-blocks.md
    - Complete component block reference
  • references/deployment-blocks.md
    - Complete deployment block reference
  • references/examples.md
    - Complete working examples for common scenarios
有关详细的块规范和高级功能,请参阅:
  • references/component-blocks.md
    - 完整的组件块参考
  • references/deployment-blocks.md
    - 完整的部署块参考
  • references/examples.md
    - 常见场景的完整工作示例