How to Use Terraform Environment Variables to Set Input Variables with TF_VAR_

Export environment variables prefixed with TF_VAR_ to automatically populate Terraform input variables before the CLI parses your configuration.

Terraform provides a built-in mechanism to inject values from your shell environment directly into your infrastructure code. By using terraform environment variables prefixed with TF_VAR_, you can dynamically set input variables without modifying .tf files or passing numerous -var flags. This functionality is implemented in the hashicorp/terraform repository through a specific prefix detection system and variable precedence logic.

Understanding the TF_VAR_ Prefix Mechanism

Terraform scans all environment variables at startup. Any variable beginning with TF_VAR_ is treated as an input variable source. The CLI strips the prefix and uses the remainder as the variable name.

This matching is case-sensitive. TF_VAR_region maps to var.region, while TF_VAR_REGION would map to a variable named REGION.

How Terraform Environment Variables Work Under the Hood

Prefix Definition in meta_vars.go

In internal/command/meta_vars.go, the constant VarEnvPrefix = "TF_VAR_" defines the magic string. The CLI uses this constant to filter the process environment and identify which environment variables should be converted to Terraform variables.

Variable Source Assignment in eval_variable.go

When Terraform processes variables, internal/terraform/eval_variable.go creates a variable source of type VariableSourceEnvVar. It attaches the description "set using the TF_VAR_%s environment variable" to track the origin of the value during debugging and logging.

Precedence and Merging in variables.go

The merging logic resides in internal/terraform/variables.go. The Variable struct records ValueFromEnvVar to indicate environment-based values. Precedence follows this strict order:

  1. Command line -var and -var-file
  2. Terraform environment variables (TF_VAR_*)
  3. Default values and terraform.tfvars

Practical Examples of Using Terraform Environment Variables

Basic String Variable

Define the variable in your configuration:

variable "region" {
  description = "AWS region"
  type        = string
}

Export the environment variable and run Terraform:

export TF_VAR_region=us-east-1
terraform plan

Terraform will output:


# var.region

  us-east-1

Complex Types (Lists and Maps)

For non-string types, export the value as a JSON-encoded string:

variable "subnets" {
  type = list(string)
}
export TF_VAR_subnets='["subnet-1111","subnet-2222"]'
terraform apply

Terraform parses the JSON string and supplies the list to the variable.

Demonstrating Precedence

Environment variables are overridden by command-line flags:

export TF_VAR_region=us-west-2
terraform apply -var="region=eu-central-1"

The final value of var.region will be eu-central-1, not us-west-2.

Debugging Variable Sources

To verify which source set a variable, enable trace logging:

TF_LOG=TRACE terraform plan

The trace includes lines such as:


[TRACE] var.region value source: set using the TF_VAR_region environment variable

Other Terraform Environment Variables (CLI Behavior)

Not all TF_* environment variables become input variables. Variables like TF_CLI_ARGS, TF_DATA_DIR, and TF_LOG are consumed by the CLI itself to modify behavior. These are handled in internal/command/cliconfig/cliconfig.go and control logging levels, plugin cache directories, and extra CLI arguments. They do not populate var.* references in your configuration.

Summary

  • Export variables with the TF_VAR_ prefix to populate Terraform input variables automatically
  • The prefix is defined in internal/command/meta_vars.go as VarEnvPrefix
  • Values are always strings; Terraform coerces them to the declared variable type
  • Precedence order: -var flags > TF_VAR_* > defaults/terraform.tfvars
  • Other TF_* variables control CLI behavior and are not exposed to configurations

Frequently Asked Questions

What is the exact prefix for Terraform environment variables?

The prefix is TF_VAR_. Any environment variable starting with this string is automatically mapped to a Terraform input variable by stripping the prefix. The remainder must exactly match the variable name declared in your configuration, as the matching is case-sensitive.

Can I use Terraform environment variables for complex types like maps and lists?

Yes. While the environment variable always contains a string value, Terraform parses it as JSON when the target variable has a complex type. For example, export TF_VAR_subnets='["subnet-1","subnet-2"]' to populate a list(string) variable, or use '{"key":"value"}' for map types.

Do Terraform environment variables override default values?

Yes. TF_VAR_* environment variables take precedence over default values defined in variable blocks and values from terraform.tfvars files. However, they are overridden by -var and -var-file command line arguments, which have the highest precedence in the variable merging logic found in internal/terraform/variables.go.

Are all TF_* environment variables treated as input variables?

No. Only variables prefixed with TF_VAR_ become input variables accessible via var.*. Other variables like TF_LOG, TF_CLI_ARGS, TF_DATA_DIR, and TF_WORKSPACE control CLI behavior, logging, and plugin caching. These are processed separately in internal/command/cliconfig/cliconfig.go and never exposed to your Terraform configuration as variables.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s https://instagit.com/install.md

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client