terraform-stacks

安装量: 809
排名: #1560

安装

npx skills add https://github.com/hashicorp/agent-skills --skill 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.

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.

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.

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//vpc/aws

When validating Stack configurations, check component source declarations rather than assuming a local modules/ directory must exist.

Component Configuration (.tfcomponent.hcl) Variable Block

Declare input variables for the Stack configuration. Variables must define a type field and do not support the validation argument.

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:

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:

Support for_each meta-argument Define aliases in the block header (not as an argument) Accept configuration through a config block

Single Provider Configuration:

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:

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 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:

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.. All inputs are provided as a single inputs object Provider references are normal values: provider.. Dependencies are automatically inferred from component references Output Block

Outputs require a type argument and do not support 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 Block

Works exactly as in traditional Terraform:

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.

removed { from = component.old_component source = "./modules/old-module"

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

Deployment Configuration (.tfdeploy.hcl) Identity Token Block

Generate JWT tokens for OIDC authentication with cloud providers:

identity_token "aws" { audience = ["aws.workload.identity"] }

identity_token "azure" { audience = ["api://AzureADTokenExchange"] }

Reference tokens in deployments using identity_token..jwt

Locals Block

Define local values for deployment configuration:

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:

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:

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:

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.

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.

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):

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.

Publish Output Block

Export outputs from a Stack for use in other Stacks (linked Stacks):

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:

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 Initialize and Validate

Generate provider lock file:

terraform stacks providers-lock

Validate Stack configuration:

terraform stacks validate

Plan and Apply

Plan a specific deployment:

terraform stacks plan --deployment=production

Apply a deployment:

terraform stacks apply --deployment=production

Common Patterns Multi-Region Deployment

variables.tfcomponent.hcl

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

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 } } }

components.tfcomponent.hcl

component "regional_infra" { for_each = var.regions source = "./modules/regional"

inputs = { region = each.value }

providers = { aws = provider.aws.regional[each.value] } }

Component Dependencies

Dependencies are automatically inferred when one component references another's output:

component "database" { source = "./modules/rds"

inputs = { subnet_ids = component.vpc.private_subnet_ids # Creates dependency }

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

Best Practices Component Granularity: Create components for logical infrastructure units that share a lifecycle Module Compatibility: Modules used with Stacks cannot include provider blocks (configure providers in Stack configuration) State Isolation: Each deployment has its own isolated state Input Variables: Use variables for values that differ across deployments; use locals for shared values Provider Lock Files: Always generate and commit .terraform.lock.hcl to version control Naming Conventions: Use descriptive names for components and deployments 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 Testing: Test Stack configurations in dev/staging deployments before production 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

Deployment Limit

HCP Terraform supports maximum 20 deployments per Stack. For more instances, use multiple Stacks or for_each within components.

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

返回排行榜