Loading...
Loading...
Comprehensive guide for working with HashiCorp Terraform Stacks. Use when creating, modifying, or validating Terraform Stack configurations (.tfcomponent.hcl, .tfdeploy.hcl files), working with stack components and deployments from local modules, public registry, or private registry sources, managing multi-region or multi-environment infrastructure, or troubleshooting Terraform Stacks syntax and structure.
npx skill4agent add hashicorp/agent-skills terraform-stacks.tfcomponent.hcl.tfdeploy.hcl.terraform.lock.hclmy-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/modules/./modules/vpcterraform-aws-modules/vpc/awsapp.terraform.io/<org-name>/vpc/awsmodules/typevalidationvariable "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 {
aws = {
source = "hashicorp/aws"
version = "~> 5.7.0"
}
random = {
source = "hashicorp/random"
version = "~> 3.5.0"
}
}for_eachconfigprovider "aws" "this" {
config {
region = var.aws_region
assume_role_with_web_identity {
role_arn = var.role_arn
web_identity_token = var.identity_token
}
}
}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
}
}
}source./modules/vpcterraform-aws-modules/vpc/awsapp.terraform.io/my-org/vpc/awsgit::https://github.com/org/repo.git//modules/vpc?ref=v1.0.0component "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 "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>inputsprovider.<type>.<alias>typepreconditionsoutput "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 {
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 {
from = component.old_component
source = "./modules/old-module"
providers = {
aws = provider.aws.this
}
}identity_token "aws" {
audience = ["aws.workload.identity"]
}
identity_token "azure" {
audience = ["api://AzureADTokenExchange"]
}identity_token.<name>.jwtlocals {
aws_regions = ["us-west-1", "us-east-1", "eu-west-1"]
role_arn = "arn:aws:iam::123456789012:role/hcp-terraform-stacks"
}deployment "production" {
inputs = {
aws_region = "us-west-1"
instance_count = 3
role_arn = local.role_arn
identity_token = identity_token.aws.jwt
}
}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
}
}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 "canary" {
deployments = [
deployment.dev,
deployment.staging
]
}
deployment_group "production" {
deployments = [
deployment.prod_us_east,
deployment.prod_us_west
]
}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.applyablecontext.plan.changes.addcontext.plan.changes.changecontext.plan.changes.removeorchestratedeployment_groupdeployment_auto_approvepublish_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 "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 providers-lockterraform stacks validateterraform stacks plan --deployment=productionterraform stacks apply --deployment=production# 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 "database" {
source = "./modules/rds"
inputs = {
subnet_ids = component.vpc.private_subnet_ids # Creates dependency
}
providers = {
aws = provider.aws.this
}
}.terraform.lock.hclfor_eachreferences/component-blocks.mdreferences/deployment-blocks.mdreferences/examples.md