---
page_title: Deployment configuration file reference
description: Stacks help you provision and coordinate your infrastructure lifecycle at scale. Learn how to write a deployment configurion to tell HCP Terraform how many times to deploy your Stack's infrastructure.
---

⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]  
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️


# Deployment configuration file reference

A deployment configuration file defines how to deploy your Stack's infrastructure. Each Stack deployment runs in its agent, wholly isolated from other Stack deployments.

Every Stack needs a deployment configuration file, `tfdeploy.hcl`, and this page describes all of the blocks you can use within a deployment configuration file. Note that none of the blocks in the deployment configuration file support [meta-arguments](/terraform/language/resources/syntax#meta-arguments).

## `deployment` block configuration

The `deployment` block is where you define how many times you want to deploy your Stack's infrastructure. Each Stack requires at least one `deployment` block, and you can add a new `deployment` block every time you want to deploy your Stack’s infrastructure again.

-> **Note**: HCP Terraform supports up to a maximum of 20 deployments.

The following list outlines field hierarchy, language-specific data types, and requirements in the `deployment` block.

### Complete configuration

When every field is defined, a `deployment` block has the following form:

```hcl
deployment "unique_name" {
  inputs = {
    key     = "value"
  }
}
```

For examples and guidance on defining deployments, refer to [Define deployment configuration](/terraform/language/stacks/deploy/config).

### Specification

This section details the fields you can configure in the `deployment` block.

Each Stack must have at least one `deployment` block, and the label of the `deployment` block must be unique within your Stack. The `deployment` block is a map that defines the appropriate input values for each Stack instance to deploy.

| Field | Description | Type | Required |
| :---- | :---- | :---- | :---- |
| `inputs` | A mapping of Stack variable names for this deployment.  The keys in this map must correspond to the names of variables defined in the Stack. The values must be valid HCL literals meeting the type constraint of those variables. | map | Required |

### Reference

For example, the following `deployment` block accepts inputs for variables named `aws_region` and `instance_count` and creates a new deployment in HCP Terraform named “production”.

```hcl
deployment "production" {
    inputs = {
        aws_region     = "us-west-1"
        instance_count = 2
    }
}
```

To learn more about defining deployments, refer to [Define deployment configuration](/terraform/language/stacks/deploy/config).

## `orchestrate` block configuration

The orchestrate block defines orchestration rules that you can use to manage your deployment plans. Your orchestration rules can automate tasks like auto-approving plans that meet specific conditions.

The following list outlines field hierarchy, language-specific data types, and requirements in the `orchestrate` block.

### Complete configuration

When every field is defined, an `orchestrate` block has the following form:

```hcl
# auto_approve is the rule type
orchestrate "auto_approve" "name_of_check" {
  check {
    condition = <the condition that HCP Terraform evaluates>
    reason ="Provide the reason why this check failed."
  }
}
```

The `orchestrate` block label includes the rule type and the rule name, which together must be unique within the Stack.

There are two orchestration rules to choose from:

* The `auto_approve` rule executes after a Stack creates a plan and automatically approves a plan if all checks pass.
* The `replan` rule executes after a Stack applies a plan, automatically triggering a replan if all the checks pass.

HCP Terraform evaluates the `check` blocks within your `orchestrate` block to determine if it should approve a plan. If all of the checks pass, then HCP Terraform approves the plan for you. If one or more `conditions` do not pass, then HCP Terraform shows the `reason` why, and you must manually approve that plan.

By default, each Stack has an `auto_approve` rule named `empty_plan`, which automatically approves a plan if it contains no changes.

### Specification

This section provides details about the fields you can configure in the `orchestrate` block.


| Field | Description | Type | Required |
| :---- | :---- | :---- | :---- |
| `check` | A block containing conditions and reasons for the orchestration rule. All checks must pass for an orchestration rule to be triggered. | block | Required |

The `check` block contains the following configurable fields.

| Field | Description | Type | Required |
| :---- | :---- | :---- | :---- |
| `condition` | An expression that determines whether the check passes. | expression | Required |
| `reason` | A message explaining why the check failed is shown in HCP Terraform, prompting you to manually approve a plan. | string | Required |

### Orchestration Context

A `check` block’s `condition` field has access to a `context` variable, which includes information about the context of the current deployment plan. The `context` variable contains the following fields.

| Field | Description | Type |
| :---- | :---- | :---- |
| `operation` | The current operation HCP Terraform is performing.  | string ("plan" or "apply") |
| `success` | Indicates whether the operation failed. If this field is `false`, then the `errors` field contains the message of why the operation failed.   | boolean |
| `plan` | An object including data about the current plan. | object |
| `errors` | A set of diagnostic error message objects. | set of objects |
| `warnings` | A set of diagnostic warning message objects. | set of objects |

The diagnostic message objects that the `context.errors` and `context.warnings` fields return includes the following information.

| Field | Description | Type |
| :---- | :---- | :---- |
| `summary` | A brief summary of the diagnostic message | string |
| `detail` | Detailed information about the diagnostic message | string |

The `context.plan` field returns an object including the following fields.

| Field | Description | Type |
| :---- | :---- | :---- |
| `mode` | The plan mode. | string ("normal", "refresh-only", or "destroy") |
| `applyable` | Whether or not the plan can be applied. | boolean |
| `changes` | A change summary object. | object |
| `component_changes` | A map of change summary objects for each component instance. | map of objects |
| `replans` | The number of replans in this plan's sequence, starting at `0`. | integer |
| `deployment` | A direct reference to the current deployment. | Deployment object containing a `deployment_name` field. |

The objects in the `context.plan.component_changes` field include the following fields.

| Field | Description | Type |
| :---- | :---- | :---- |
| `add` | Number of resources to be added. | integer |
| `change` | Number of resources to be changed. | integer |
| `import` | Number of resources to be imported. | integer |
| `remove` | Number of resources to be removed. | integer |
| `total` | Total number of resource actions. | integer |

The object in the `context.plan.deployment` field includes the following fields.

| Field | Description | Type |
| :---- | :---- | :---- |
| `deployment_name` | The name of the current deployment HCP Terraform is running this plan on.  You can use this field to check which deployment is running this plan. For example, you can check if this plan is on your production deployment: `context.plan.deployment == deployment.production`. | string |

### Reference

For example, the following `orchestrate` block automatically approves deployments if a component has not changed.

```hcl
orchestrate "auto_approve" "no_pet_changes" {
  check {
    condition = context.plan.component_changes["component.pet"].total == 0
    reason    = "Changes proposed to pet component."
  }
}
```

If nothing changes in the `component.pet` component, HCP Terraform automatically approves the plan.

## `identity_token` block configuration

The `identity_token` block defines a JSON Web Token (JWT) that Terraform generates for a given deployment if that `deployment` block references an `identity_token` in its `inputs`.

You can directly pass the token generated by the `identity_token` block to a provider's configuration for OIDC authentication. For more information on authenticating a Stack using OIDC, refer to [Authenticate a Stack](/terraform/language/stacks/deploy/authenticate).

### Complete configuration

When every field is defined, an `identity_token` block has the following form:

```hcl
identity_token "unique_to_stack_name" {
  audience = ["audience this token is intended for"]
}
```

### Specification

This section provides details about the fields you can configure in the `identity_token` block.

| Field | Description | Type | Required |
| :---- | :---- | :---- | :---- |
| `audience` | The audience of your token is the resource(s) that uses this token after Terraform generates it. You specify an audience to ensure that the cloud service authorizing the workload is confident that the token you present is intended for that service. | set of strings | Required |

### Reference

Once defined, you can reference an identity token's `jwt` attribute in a deployment's inputs. For example, below we generate a token for a particular role ARN in AWS.

```hcl
# main.tfdeploy.hcl
identity_token "aws" {
  audience = ["aws.workload.identity"]
}

deployment "staging" {
  inputs = {
    aws_region = "eu-west-1"
    role_arn   = "arn:aws:iam::123456789101:role/my-oidc-role"
    aws_token  = identity_token.aws.jwt
  }
}
```

Terraform generates an identity token that you can use in your Stack configuration to configure your AWS provider with your role in AWS.

```hcl
# providers.tfstack.hcl

variable "aws_token" {
  type      = string
  ephemeral = true
}

variable "aws_region" {
  type = string
}

variable "aws_role" {
  type = string
}

provider "aws" "this" {
  config {
    region = var.aws_region
    assume_role_with_web_identity {
      role_arn           = var.aws_role
      web_identity_token = var.aws_token
    }
  }
}
```

With this setup, every time your `staging` deployment performs a plan or apply operation, we authenticate with AWS using your established ARN role and a new JWT token. For more information on authenticating a Stack using OIDC, refer to [Authenticate a Stack](/terraform/language/stacks/authenticate).

## `store` block configuration

Use the `store` block to define key-value secrets in your deployment configuration. After storing a secret, you can reference it in your deployment block input variable values.

When you define a `store` block, you define two headers: the first specifies the store type, and the second is the store's name.

When every field is defined, a `store` block has the following form.

```hcl
store "store_type" "store_name" {
  <store type specific arguments>
}
```

A store’s type defines where Terraform should look for that store’s credentials and how to decode the credentials it finds. You cannot share arguments across store types.

### `varset` specification and configuration

Use the `varset` store to enable your Stacks to access [variable sets](/terraform/cloud-docs/workspaces/variables/managing-variables#variable-sets) in HCP Terraform. Your Stack must have access to the variable set you are targeting, meaning it must be globally available or assigned to the project containing your Stack.

This section details the fields you can configure in the `store` block that uses the `varset` store type.

```hcl
store "varset" "store_name" {
  id       = "<variable_set_id>"
  category = <"terraform" or "env">
}
```

The `varset` store type accepts the following fields.

| Field | Description | Type | Required |
| :---- | :---- | :---- | :---- |
| `id` | The external ID of the variable set you want to access. | string | Required |
| `category` | The `category` argument specifies whether to use Terraform or environment variables from the variable set. Specify "terraform" or "env" depending on the variable you want to access. | string | Required |

The `store.varset` block can only use a variable set’s Terraform or environment variables. You can define two `store` blocks if you need to access Terraform and environment variables in your deployment configuration.

```hcl
store "varset" "tokens" {
  id       = "varset-###"
  category = "terraform"
}

store "varset" "available_regions" {
  id       = "varset-###"
  category = "env"
}

deployment "main" {
  inputs = {
    regions   = store.varset.available_regions.regions
    tfe_token = store.varset.tokens.tfe_token
  }
}
```

You can access specific environment variables by key from the `store.varset.available_regions` store, and you can access specific Terraform variables by key using the `store.varset.tokens` store.

### Reference

For example, if you have an HCP Terraform [variable set](/terraform/cloud-docs/workspaces/variables/managing-variables#variable-sets) that contains a value you want to use in your deployment, you can create a `store` block to access that variable set.

```hcl
store "varset" "tokens" {
  id       = "<variable_set_id>"
  category = "terraform"
}

deployment "main" {
  inputs = {
    token = store.varset.tokens.example_token
  }
}
```

You cannot access an entire store and must specifically access individual keys within that store. Meaning, we can access your example’s `example_token` variable by accessing the store’s `varset` type, `store.varset`, then accessing the specific store, `store.varset.tokens.example_token`.

## `locals` block configuration

A local value assigns a name to an expression, so you can use the name multiple times within your Stack configuration instead of repeating the expression. The `locals` block works exactly as it does in traditional Terraform configurations. Learn more about [the `locals` block](/terraform/language/values/locals).

## `publish_output` block configuration

The `publish_output` block requires at least Terraform version `terraform_1.10.0-alpha20241009` or higher. Download [latest version of Terraform](https://releases.hashicorp.com/terraform/) to use the most up-to-date functionality.

The `publish_output` block specifies a value to export from your current Stack, which other Stacks in the same project can consume. Declare one `publish_output` block for each value to export from your Stack.

### Complete configuration

When every field is defined, a `publish_output` block has the following form:

<CodeBlockConfig hideClipboard>

```hcl
publish_output "output_name" {
  description = "Description of the purpose of this output"
  value       = deployment.deployment_name.some_value
}
```

</CodeBlockConfig>

### Specification

This section provides details about the fields you can configure in the output block.

| Field | Description | Type | Required |
| :---- | :---- | :---- | :---- |
| `description` | A human-friendly description for the output. | string | Optional |
| `value` | The value to output.  | any | Required |

### Reference

For example, you could output the VPC ID from your networking deployment, making it available to other Stacks to input.

<CodeBlockConfig filename="network.tfdeploy.hcl">

```hcl
# Network Stack's deployment configuration

publish_output "vpc_id" {
  description = "The networking Stack's VPC's ID."
  value       = deployment.network.vpc_id
}
```

</CodeBlockConfig>

To learn more about passing information between Stacks, refer to [Pass data from one Stack to another](/terraform/language/stacks/deploy/pass-data).

## `upstream_input` block configuration

The `upstream_input` block requires at least Terraform version `terraform_1.10.0-alpha20241009` or higher. Download [latest version of Terraform](https://releases.hashicorp.com/terraform/) to use the most up-to-date functionality.

The `upstream_input` block specifies another Stack in the same project to consume outputs from. Declare an `upstream_input` block for each Stack you want to reference. If an output from a upstream Stack changes, HCP Terraform automatically triggers runs for any Stacks that depend on those outputs.

To learn more about passing information between Stacks, refer to [Pass data from one Stack to another](/terraform/language/stacks/deploy/link-stacks).

### Complete configuration

When every field is defined, an `upstream_input` block has the following form:

<CodeBlockConfig hideClipboard>

```hcl
upstream_input "upstream_stack_name" {
  type   = "stack"
  source = "app.terraform.io/{organization_name}/{project_name}/{upstream_stack_name}"
}
```

</CodeBlockConfig>

### Specification

This section provides details about the fields you can configure in the `upstream_input` block.

| Field | Description | Type | Required |
| :---- | :---- | :---- | :---- |
| `type` | The only supported type is “stack”. | string | Required |
| `source` | The upstream Stack’s URL, in the format: `"app.terraform.io/{organization_name}/{project_name}/{upstream_stack_name}"` | string | Required |

### Reference

For example, you could input a VPC ID from an upstream Stack that manages your shared networking service. You can use the `upstream_input` block to pass information from your network Stack into your application Stack.

<CodeBlockConfig filename="application.tfdeploy.hcl">

```hcl
# Application Stack's deployment configuration

upstream_input "network_stack" {
  type   = "stack"
  source = "app.terraform.io/hashicorp/Default Project/networking-stack"
}

deployment "application" {
  inputs = {
    vpc_id = upstream_input.network_stack.vpc_id
  }
}
```

</CodeBlockConfig>

Your application Stack can now securely consume and use outputs from your network Stack. To learn more about passing information between Stacks, reference [Pass data from one Stack to another](/terraform/language/stacks/deploy/pass-data).
