In this article, we will look at what Terraform environment variables are, when and why you would use them, and how to set them with examples of each! Let’s jump straight in!
We will cover:
What is a Terraform environment variable?
A Terraform environment variable is a key-value pair set within the environment where Terraform is running. Terraform refers to a number of environment variables to customize various aspects of its behavior. They can be used, for example, to specify the location of the Terraform configuration files, set provider credentials, or define backend configurations. These variables provide configuration information to Terraform without having to hardcode it into the configuration files.
Environment variables can be set on the command line, within scripts, or by using the operating system’s environment variable settings.
For reference, using the GUI in a Windows OS, they can be set Under System Properties → Advanced → Environment Variables → New system variable.
On the command line in a Windows system, you can use the SET
command as an equivalent to the export
on Linux based system, and view the current value using %<variable name>%
:
set TF_LOG=trace
%TF_LOG%
In Spacelift, environment variables can be defined directly on stacks and modules, as well as on contexts attached to those. Read more about using environment variables in our documentation.
To read and use environment variables in Terraform runs, you simply need to define a Terraform variable, and then add a value for it in the environment:
variable "name" {
type = string
}
For example, if your variable is called name, as above, you will need to save its value in an environment variable called TF_VAR_name. Terraform checks the environment when you are running the code, and to ensure that you can name your variable however you want, it checks for names that are prefixed with TF_VAR.
Terraform supports several types of environment variables that can be used to configure and manage different aspects of your infrastructure. Here are the main types of environment variables used in Terraform.
The following examples in this article use the export
command, which is native to Linux and MacOS (but is not available on a Windows OS).
1) TF_VAR_name
As well as defining variables using a .tfvars
files and directly on the command line, this environment variable can be used to set values for variables in your Terraform configuration.
Note that defining variables this way is a fallback if variable values are not found elsewhere.
The variable name you want to set the value for should be in the format _name, e.g., for a variable named region, you would specify TF_VAR_region as the variable name. This can be useful when running Terraform in automation, or when running a sequence of Terraform commands in succession with the same variables.
export TF_VAR_region=uksouth
export TF_VAR_regionlist='[uksouth,ukwest,useast2]'
export TF_VAR_tagmap='{ Environment = "dev", Project = "demo" }'
2) TF_LOG
The TF_LOG variable enables detailed logs in stderr, for debugging purposes:
export TF_LOG=trace
You can set TF_LOG
to one of the log levels (in order of decreasing verbosity) TRACE
, DEBUG
, INFO
, WARN
or ERROR
to change the verbosity of the logs.
Setting TF_LOG
to JSON
outputs logs at the TRACE
level or higher, and uses a parseable JSON encoding for formatting.
You can turn off logging when you have finished debugging:
export TF_LOG=off
3) TF_LOG_PATH
When TF_LOG
is set, you can also use the TF_LOG_PATH
variable to set the location where the log should persist its output to. The below example logs to a file called terraform.log
in the local directory.
export TF_LOG_PATH=./terraform.log
4) TF_INPUT
TF_INPUT environment variable is useful when you want to replicate the -input=false
flag behavior from the command line in an environment variable by specifying a value of 0
or FALSE
. This disables prompts for input for variables that have not been specified.
export TF_INPUT=0
5) TF_CLI_ARGS and TF_CLI_ARGS_name
TF_CLI_ARGS
is used to specify additional arguments to the command line. Arguments are inserted directly after the subcommand (such as plan
) and before any flags specified directly on the command line. This behavior ensures that flags on the command line take precedence over environment variables.
For example, to run terraform plan
with the debug mode enabled and specify the location of the state file, you can set the TF_CLI_ARGS
variable to -state=terraform.tfstate -debug
, which will pass the -state
and -debug
options to Terraform CLI.
export TF_CLI_ARGS="-state=terraform.tfstate -debug"
When the terraform plan
command is run, Terraform uses the state file specified and outputs additional debugging information to the console.
A named command can also be specified, which will only affect that command. This is done using the TF_CLI_ARGS_name
variable.
For example, to specify that only plans never refresh:
export TF_CLI_ARGS_plan="-refresh=false"
6) TF_DATA_DIR
By default, Terraform working data is written into a .terraform
subdirectory of the current directory. The TF_DATA_DIR can be used to change the path where this data is held (useful in rare cases where the working directory is not writeable).
In automation, this must be set at each stage of the Terraform workflow for each command, e.g. terraform init
, terraform plan
, terraform apply
— as each command will need to reference the working directory if it is changed from the default to find modules and configuration information.
export TF_DATA_DIR=./mydirectory/terraform
7) TF_WORKSPACE
This is the environment variable equivalent of setting your workspace using:
terraform workspace select my_workspace_name
This is useful in automation as it overrides any workspace selection but is not recommended when using Terraform interactively as it is easy to set and forget, which might cause inadvertent changes to the wrong Terraform state.
For example:
export TF_WORKSPACE=my_workspace_name
8) TF_IN_AUTOMATION
This is a variable used to set a purely cosmetic change to Terraform’s human-readable output, which prevents it from suggesting specific commands to run next after one command has been completed.
In automation, this wouldn’t be possible as the environment is non-interactive, so removing these suggestions makes the output less confusing. To use it, set it to any non-empty value.
export TF_IN_AUTOMATION=true
9) TF_CLI_CONFIG_FILE
Used to specify the location of the Terraform CLI configuration file. This is a file specified as .terraformrc
or terraform.rc
which configures per-user settings for CLI behaviors that apply across all Terraform working directories.
export TF_CLI_CONFIG_FILE=”./mydirectory/.terraformrc-custom”
10) TF_IGNORE
When debugging large repositories with .terraformignore
files, the TF_IGNORE variable can be used to get Terraform to output debug messages to display ignored files and folders. It should be set to trace
.
Files listed in a .terraformignore
plan are simply a list of files that should not be considered as part of the configuration to speed up deployments when a large number of file exist.
export TF_IGNORE=trace
11) TF_REGISTRY_DISCOVERY_RETRY
Set TF_REGISTRY_DISCOVERY_RETRY
to configure the max number of request retries, the remote registry client will attempt for client connection errors or 500-range responses that are safe to retry.
export TF_REGISTRY_DISCOVERY_RETRY=10
This example sets the value of TF_REGISTRY_DISCOVERY_RETRY
to ten, which means that registry discovery operations will be retried up to ten times before failing.
12) TF_REGISTRY_CLIENT_TIMEOUT
This variable can be configured to increase the default client timeout to the remote registry during extraneous circumstances.
The default client timeout for requests to the remote registry is 10s.
export TF_REGISTRY_CLIENT_TIMEOUT=30
13) TF_STATE_PERSIST_INTERVAL
By default, Terraform persists the state to a remote backend every 20 seconds, but this value can be overridden by setting the TF_STATE_PERSIST_INTERVAL. Keep in mind that if you define a value lower than the minimum allowed for the backend, Terraform will default to the backend’s minimum interval. The value must be specified in seconds:
export TF_STATE_PERSIST_INTERVAL=50
14) TF_PLUGIN_CACHE_DIR
The TF_PLUGIN_CACHE_DIR is used to specify a directory where Terraform can cache provider plugins. This allows Terraform to reuse the same plugins across multiple projects or runs, rather than downloading them every time when terraform init
runs.
export TF_PLUGIN_CACHE_DIR="$~/.terraform.d/plugin-cache"
If you are using a module and when you are specifying the variables for it, you can add values to them with environment variables.
Let’s take a look at a simple example. Suppose you have the following module that generates random pet names:
resource "random_pet" "this" {
prefix = var.prefix
}
variable "prefix" {
type = string
}
Now, let’s call the module:
module "pet" {
source = "./module"
prefix = var.prefix
}
variable "prefix" {
type = string
}
Next, let’s add an environment variable for the prefix:
export TF_VAR_prefix=dog
If we apply the code, we will see that our random pet name will be generated with the dog prefix we’ve set above:
+ resource "random_pet" "this" {
+ id = (known after apply)
+ length = 2
+ prefix = "dog"
+ separator = "-"
}
Plan: 1 to add, 0 to change, 0 to destroy.
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes
module.pet.random_pet.this: Creating...
module.pet.random_pet.this: Creation complete after 0s [id=dog-evolved-dane]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
For this example, we will use the AWS provider. There are many ways in which you can configure authentication, but we will explore the most basic one, which is using an access key and a secret key. This is what it looks like with hardcoded values:
provider "aws" {
region = "eu-west-1"
access_key = "my-access-key"
secret_key = "my-secret-key"
}
AWS gives us the ability to source the credentials in multiple ways (parameters in the provider configuration, environment variables, shared credentials files, and others). If we want to use environment variables, the AWS provider automatically reads values from the following variables:
- AWS_ACCESS_KEY_ID
- AWS_SECRET_ACCESS_KEY
- AWS_SESSION_TOKEN
- AWS_REGION
- AWS_DEFAULT_REGION
So you can set these if you’d like, by simply doing an export in your CLI. I will also show you how to configure custom ones by defining variables inside your Terraform configuration:
provider "aws" {
region = var.region
access_key = var.access_key
secret_key = var.secret_key
}
variable "region" {
type = string
}
variable "access_key" {
type = string
}
variable "secret_key" {
type = string
}
Now to provide environment variables for these we could run the following in our terminal:
export TF_VAR_region="region"
export TF_VAR_access_key="access_key"
export TF_VAR_secret_key="secret_key"
Ensure you change the values to the ones from your AWS account, and that’s it.
Terraform is really powerful, but to achieve an end-to-end secure GitOps approach, you need to use a product that can run your Terraform workflows. Spacelift takes managing Terraform to the next level by giving you access to a powerful CI/CD workflow and unlocking features such as:
- Policies (based on Open Policy Agent) — You can control how many approvals you need for runs, the kind of resources you can create, and the kind of parameters these resources can have, and you can also control the behavior when a pull request is open or merged.
- Multi-IaC workflows — Combine Terraform with Kubernetes, Ansible, and other IaC tools such as OpenTofu, Pulumi, and CloudFormation, create dependencies among them, and share outputs
- Build self-service infrastructure — You can use Blueprints to build self-service infrastructure; simply complete a form to provision infrastructure based on Terraform and other supported tools.
- Integrations with any third-party tools — You can integrate with your favorite third-party tools and even build policies for them. For example, you can integrate security tools in your workflows using Custom Inputs.
Spacelift enables you to create private workers inside your infrastructure, which helps you execute Spacelift-related workflows on your end. The documentation provides more information on configuring private workers.
If you want to elevate your Terraform management, create a free account for Spacelift today or book a demo with one of our engineers.
Terraform environment variables provide a flexible and secure way to manage configuration information, making it easier to use Terraform in a variety of environments and scenarios.
Environment variables are not required when using Terraform, but they can be helpful to change some of Terraform’s default behaviors in unusual situations.
Note: New versions of Terraform are placed under the BUSL license, but everything created before version 1.5.x stays open-source. OpenTofu is an open-source version of Terraform that expands on Terraform’s existing concepts and offerings. It is a viable alternative to HashiCorp’s Terraform, being forked from Terraform version 1.5.6.
Achieve Terraform at Scale
Spacelift effectively manages Terraform state, more complex workflows, supports policy as code, programmatic configuration, context sharing, drift detection, resource visualization and includes many more features.