Terraform
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.
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:
deployment "unique_name" {
inputs = {
key = "value"
}
}
For examples and guidance on defining deployments, refer to Define deployment configuration.
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 |
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”.
deployment "production" {
inputs = {
aws_region = "us-west-1"
instance_count = 2
}
}
To learn more about defining deployments, refer to Define deployment configuration.
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:
# 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.
For example, the following orchestrate
block automatically approves deployments if a component has not changed.
orchestrate "auto_approve" "no_pet_changes" {
check {
# Check that the pet component has no changes
condition = context.plan.component_changes["component.pet"].total == 0
reason = "Changes proposed to pet component."
}
}
By default, each Stack has an auto-approve
rule named empty_plan
, which auto-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 |
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.
Complete configuration
When every field is defined, an identity_token
block has the following form:
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 |
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.
# 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.
# 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.region
assume_role_with_web_identity {
role_arn = var.aws_role
# Your configuration anticipates the aws_token we created
# with the indentity_token block in your deployments file.
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.
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.
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.
For example, if you have an HCP Terraform variable set that contains a value you want to use in your deployment, you can create a store
block to access that variable set.
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
.
varset
specification and configuration
Use the varset
store to enable your Stacks to access 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.
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.
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.
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.