Where Terraform reads its settings
The CLI is configured in two places:
- The
~/.terraformrcfile (Linux/macOS) or%APPDATA%\terraform.rc(Windows). HCL format. Read once when any command starts. - The
TF_*environment variables. Read on every terraform run. Where values overlap, they take priority overterraformrc.
These files are about the CLI, not about project configuration. They hold no resources and no state. They describe how you prefer to work with terraform, not what terraform creates.
~/.terraformrc and what usually goes in it
plugin_cache_dir = "$HOME/.terraform.d/plugin-cache"
disable_checkpoint = true
credentials "app.terraform.io" {token = "..."
}
plugin_cache_diris a shared folder for downloaded plugins across all your projects. Without it, everyterraform initdownloads the providers again into the local.terraform/, and you end up with duplicated gigabytes. With the cache,initfor a new project takes seconds.disable_checkpoint = trueturns off the background check for "is there a newer version of Terraform". It is not critical, but on offline networks it removes the noise.credentialsis a token for private registries (Terraform Cloud, Spacelift). You usually do not need it in a learning course.
You have to create the folder for plugin_cache_dir yourself: mkdir -p ~/.terraform.d/plugin-cache.
Environment variables
Controlling output and behavior
TF_LOGis the log level. Values:TRACE,DEBUG,INFO,WARN,ERROR. AtDEBUGyou see every HTTP call to the provider. This is your main debugging tool whenapplyfails with an error you cannot make sense of:bashTF_LOG=DEBUG terraform apply 2> debug.log
TF_LOG_PATHis where to write the log. If it is not set, the log goes to stderr.TF_INPUT=0turns off the interactive prompts (for CI).TF_IN_AUTOMATION=truetells terraform it is running in a pipeline. It trims the output and drops the hints about next steps.
Passing variables into HCL
TF_VAR_namesets the value of thevariable "name"from HCL. For example:bashexport TF_VAR_bucket_name="my-bucket-from-env"
terraform plan
TF_CLI_ARGSadds flags to any command. For example, to always pass-input=falseon every run without writing it out in each call:bashexport TF_CLI_ARGS="-input=false"
TF_CLI_ARGS_plan,TF_CLI_ARGS_apply, and so on. The same thing, but only for a specific command.
Controlling the cache and backend
TF_DATA_DIRis where terraform creates.terraform/. By default it sits next to the.tffiles; you can move it to/tmp/if the project is on a read-only filesystem.TF_CLI_CONFIG_FILEis the path to an alternativeterraformrcfile. This helps when CI needs one configuration file and your local machine needs another.
How to use TF_LOG
The most common case: terraform apply fails with
"Error: failed to get versions..." and no detail. You run the same thing
with DEBUG:
TF_LOG=DEBUG TF_LOG_PATH=./tf.log terraform apply
tf.log will hold the full HTTP exchange: which URL it went to, what
response it got, and where the provider broke. You can often see that it hit
a proxy, hit DNS, or got a 429 from the registry.
Levels:
| Level | When to use it |
|---|---|
ERROR | Errors only. The default with no flag. |
WARN | Plus warnings (deprecated, retries). |
INFO | Plus the basic steps (init, plan, apply phases). |
DEBUG | Plus HTTP calls. The most useful level for everyday debugging. |
TRACE | Plus the internals (graph expansion, parsing). Verbose, rarely needed. |
Pitfalls
TF_VAR_nameis case sensitive.TF_VAR_Regionfeeds the variableRegion, notregion. It is best to keep your variable names lowercase.TF_CLI_ARGSis concatenated with the real flags. If the env hasTF_CLI_ARGS="-no-color"and you runterraform plan -no-color, the provider sees two-no-colorflags. That is usually harmless, but when a meaningful flag is duplicated the behavior is unpredictable.plugin_cache_dirdoes not lock versions. The cache only saves you the download. Versions are still pinned by the [[tf-lockfile|lockfile]].- TF_LOG can print secrets. A DEBUG log shows the headers and bodies of
HTTP requests. Do not post a raw log in an issue: filter out
Authorization,*_token, and*_key. ~/.terraformrcand the projectproviderconfiguration are different things. terraformrc has no regions and does not name resources; the region goes in the [[tf-provider-block|provider block]].