All skills
hashicorp avatar

/terraform-stacks

@4451cec official
by hashicorphashicorp/agent-skills880 stars
130

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.

Use this Skill: https://skilld.dev/gh/hashicorp/agent-skills/terraform-stacks

This session only. Nothing lands on disk.

referencescomponent-blocks.md

≈2.5k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Component Configuration Block Reference

Complete reference for all blocks available in Terraform Stack component configuration files (.tfcomponent.hcl).

Table of Contents

  1. Variable Block
  2. Required Providers Block
  3. Provider Block
  4. Component Block
  5. Output Block
  6. Locals Block
  7. Removed Block

Variable Block

Declares input variables for Stack configuration.

Syntax

variable "variable_name" {
  type        = <type>
  description = "<description>"
  default     = <value>
  sensitive   = <bool>
  nullable    = <bool>
  ephemeral   = <bool>
}

Arguments

  • type (required): Data type (string, number, bool, list, map, object, set, tuple, any)
  • description (optional): Variable description
  • default (optional): Default value
  • sensitive (optional, default false): Mark as sensitive to redact from logs
  • nullable (optional, default true): Whether null is allowed
  • ephemeral (optional, default false): Do not persist to state file

Differences from Traditional Terraform

  • type is required (not optional)
  • validation argument is not supported

Examples

variable "aws_region" {
  type        = string
  description = "AWS region for infrastructure"
  default     = "us-west-1"
}

variable "identity_token" {
  type        = string
  description = "OIDC identity token"
  ephemeral   = true
}

variable "subnet_config" {
  type = object({
    cidr_block           = string
    availability_zone    = string
    map_public_ip        = bool
  })
}

For complete variable examples in context, see examples.md.

Required Providers Block

Declares provider dependencies.

Syntax

required_providers {
  <provider_name> = {
    source  = "<source>"
    version = "<version_constraint>"
  }
}

Arguments

  • source (required): Provider source address (e.g., "hashicorp/aws")
  • version (optional): Version constraint (e.g., "~> 5.0")

Examples

required_providers {
  aws = {
    source  = "hashicorp/aws"
    version = "~> 5.7.0"
  }

  random = {
    source  = "hashicorp/random"
    version = "~> 3.5.0"
  }

  azurerm = {
    source  = "hashicorp/azurerm"
    version = ">= 3.0"
  }
}

Provider Block

Configures provider instances.

Syntax

provider "<provider_type>" "<alias>" {
  for_each = <map_or_set>  # Optional

  config {
    <provider_arguments>
  }
}

Arguments

  • provider_type (label 1, required): Provider type (e.g., "aws", "azurerm")
  • alias (label 2, required): Unique identifier for this provider configuration
  • for_each (optional): Create multiple provider instances from a map or set
  • config (required): Nested block containing provider-specific configuration

Key Differences from Traditional Terraform

  1. Alias is defined in block header, not as an argument
  2. Configuration goes in a nested config block
  3. Supports for_each meta-argument
  4. Provider configurations are treated as first-class values

Example

provider "aws" "main" {
  config {
    region = var.aws_region

    assume_role_with_web_identity {
      role_arn           = var.role_arn
      web_identity_token = var.identity_token
    }
  }
}

For complete provider examples including for_each and multi-cloud patterns, see examples.md.

Component Block

Defines infrastructure components to include in the Stack.

Syntax

component "<component_name>" {
  for_each = <map_or_set>  # Optional

  source = "<module_source>"

  inputs = {
    <input_name> = <value>
  }

  providers = {
    <provider_local_name> = provider.<type>.<alias>[<key>]
  }
}

Arguments

  • component_name (label, required): Unique identifier for this component
  • for_each (optional): Create multiple component instances
  • source (required): Module source (see Source Argument below)
  • version (optional): Version constraint for registry-based sources only
  • inputs (required): Map of input variables for the module
  • providers (required): Map of provider configurations

Source Argument

The source argument accepts the same module sources as traditional Terraform configurations.

Local File Path:

source = "./modules/vpc"
source = "../shared-modules/networking"

Public Terraform Registry:

source = "terraform-aws-modules/vpc/aws"
source = "hashicorp/consul/aws"

Format: <NAMESPACE>/<NAME>/<PROVIDER>

Private HCP Terraform Registry:

source = "app.terraform.io/my-org/vpc/aws"
source = "app.terraform.io/example-corp/networking/azurerm"

Format: <HOSTNAME>/<ORGANIZATION>/<MODULE_NAME>/<PROVIDER_NAME>

  • HCP Terraform (SaaS): Use hostname app.terraform.io
  • Terraform Enterprise: Use your instance hostname (e.g., terraform.mycompany.com)
  • Generic hostname: Use localterraform.com for deployments spanning multiple Terraform Enterprise instances

Git Repository:

source = "git::https://github.com/org/repo.git//modules/vpc?ref=v1.0.0"
source = "git::ssh://git@github.com/org/repo.git//modules/vpc?ref=main"

HTTP/HTTPS Archive:

source = "https://example.com/modules/vpc-module.tar.gz"

Version Argument

The version argument is supported only for registry-based sources (public and private registries). Local file paths and Git sources do not support the version argument.

component "vpc" {
  source  = "app.terraform.io/my-org/vpc/aws"
  version = "~> 2.0"  # Semantic versioning constraint

  inputs = {
    cidr_block = var.vpc_cidr
  }

  providers = {
    aws = provider.aws.main
  }
}

Note: Modules sourced from local file paths always share the same version as their caller and cannot have independent version constraints.

Component References

Access component outputs using: component.<name>.<output>

For components with for_each: component.<name>[<key>].<output>

Examples

Basic Component:

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

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

  providers = {
    aws = provider.aws.main
  }
}

Component with Dependencies:

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

  inputs = {
    vpc_id             = component.vpc.vpc_id
    subnet_ids         = component.vpc.private_subnet_ids
    security_group_ids = [component.security.database_sg_id]
    engine_version     = var.db_engine_version
  }

  providers = {
    aws = provider.aws.main
  }
}

For complete component examples including for_each, multi-region, public registry, and multi-provider patterns, see examples.md.

Output Block

Exposes values from Stack configuration.

Syntax

output "<output_name>" {
  type        = <type>
  description = "<description>"
  value       = <expression>
  sensitive   = <bool>
  ephemeral   = <bool>
}

Arguments

  • output_name (label, required): Unique identifier for this output
  • type (required): Data type of the output
  • description (optional): Output description
  • value (required): Expression to output
  • sensitive (optional, default false): Mark as sensitive
  • ephemeral (optional, default false): Ephemeral value

Differences from Traditional Terraform

  • type is required
  • precondition block is not supported

Examples

output "vpc_id" {
  type        = string
  description = "VPC ID"
  value       = component.vpc.vpc_id
}

output "instance_details" {
  type = object({
    id         = string
    public_ip  = string
    private_ip = string
  })
  description = "EC2 instance details"
  value = {
    id         = component.compute.instance_id
    public_ip  = component.compute.public_ip
    private_ip = component.compute.private_ip
  }
}

For complete output examples including sensitive outputs and for expressions, see examples.md.

Locals Block

Defines local values for reuse within the Stack configuration.

Syntax

locals {
  <name> = <expression>
}

Example

locals {
  common_tags = {
    Environment = var.environment
    ManagedBy   = "Terraform Stacks"
    Project     = var.project_name
  }

  name_prefix = "${var.project_name}-${var.environment}"

  region_config = {
    for region in var.regions : region => {
      name_suffix    = region
      instance_count = var.environment == "prod" ? 3 : 1
    }
  }
}

Removed Block

Declares components to be removed from the Stack.

Syntax

removed {
  from   = component.<component_name>
  source = "<original_module_source>"

  providers = {
    <provider_name> = provider.<type>.<alias>
  }
}

Arguments

  • from (required): Reference to the component being removed
  • source (required): Original module source
  • providers (required): Provider configurations needed for removal

Important Notes

  • Required for safe component removal
  • Must include all providers the component used
  • Do not remove providers before removing components that use them

Examples

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

  providers = {
    aws = provider.aws.main
  }
}

removed {
  from   = component.legacy_regional
  source = "registry.terraform.io/example/legacy/aws"

  providers = {
    aws    = provider.aws.main
    random = provider.random.main
  }
}

Provider References in Component Blocks

Single Provider

providers = {
  aws = provider.aws.main
}

Multiple Providers

providers = {
  aws    = provider.aws.main
  random = provider.random.main
  tls    = provider.tls.main
}

Provider from for_each

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

Aliased Providers in Module

If module requires specific provider aliases:

providers = {
  aws.source = provider.aws.us_east
  aws.dest   = provider.aws.eu_west
}

Source: SKILL.md on GitHub

1 warning17d5 checks · Risk SAFE
  • Gen Agent Trust Hub17d

    This skill serves as a technical reference guide and documentation suite for managing infrastructure deployments using stack configurations. It provides structural examples, CLI usage guidelines, and API monitoring practices that follow industry-standard workflows. No security concerns were identified.

  • Socket17d

    No alerts

  • Snyk17d

    Risk: LOW · No issues

  • Runlayer7mo

    5/7 files flagged

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at 4451cec. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 3 days ago.

Activeupdated 2 months ago
Other metadata
metadata
{
  "lifecycle-status": "active",
  "copyright": "Copyright IBM Corp. 2026",
  "version": "0.0.1"
}
  • terraform
  • hcl
  • infrastructure-as-code
  • stacks
  • multi-environment
  • deployment
  • hcp-terraform
  • orchestration
  • components
  • oidc

README badge

README badge for hashicorp/agent-skills/terraform-stacks

Provides configuration and deployment patterns for Terraform Stacks, HashiCorp's declarative infrastructure orchestration layer. Covers component definitions, provider configuration with OIDC workload identity, deployment instances across environments, and HCP Terraform integration including variable sets and linked Stacks. Requires Terraform v1.13 or later.

Generated from the current SKILL.md.

What Terraform version is required?
Terraform v1.13.x or later is required to use Terraform Stacks and the CLI plugin. Specify the exact version in a .terraform-version file at the root of your Stack repository.
What file extensions do Stacks use?
Component configuration uses .tfcomponent.hcl and deployment configuration uses .tfdeploy.hcl. Both must be at the root level of the Stack repository.
How do I reference module sources?
Components can reference modules from local paths (./modules/vpc), the public registry (terraform-aws-modules/vpc/aws), private registry (app.terraform.io/org-name/vpc/aws), or Git sources (git::https://...). A modules/ directory is only required when using local module sources.
What authentication method does this skill recommend?
Use workload identity (OIDC) with identity_token blocks and assume_role_with_web_identity in provider configuration. This avoids long-lived static credentials and provides temporary, scoped credentials per deployment run.
How do I destroy a deployment?
Set destroy = true in the deployment block, upload the configuration, approve the destroy run, then remove the deployment block entirely.

Generated from the current SKILL.md. These answers refresh after source changes.