linuxlab.io
Tutorials▾
  • Linux & networking
    File system, processes, TCP/IP, BGP and OSPF
    →
  • Terraform & IaC
    HCL, state, plan/apply on a LocalStack sandbox
    →
  • Git & GitHub
    Object model, plumbing, branching, GitHub Actions
    →
All tutorials →
PricingAboutSign inCreate account
/
Intro
Lessons
Footer
linuxlab-TutorialsPricingAboutPrivacy & cookies
Copyright © 2026 LinuxLab. All rights reserved.
linuxlab.io
Tutorials▾
  • Linux & networking
    File system, processes, TCP/IP, BGP and OSPF
    →
  • Terraform & IaC
    HCL, state, plan/apply on a LocalStack sandbox
    →
  • Git & GitHub
    Object model, plumbing, branching, GitHub Actions
    →
All tutorials →
PricingAboutSign inCreate account
/
  • Introduction
  • Lessons
  • How it works
  • Knowledge base
  • Cheat sheet
  • Capstone
  • Interview prep
home/terraform/kb/Variables & outputs/tf-variable-sources

kb/variables ── Variables & outputs ── beginner

Where Terraform reads variable values from

Six sources, in priority order: -var in CLI > -var-file > *.auto.tfvars (alphabetically) > terraform.tfvars > TF_VAR_* env > default. If none of these supply a value, Terraform prompts interactively. Understanding this order matters for CI/CD.

view as markdown

Six sources of values

Terraform reads variable values from several places. From highest to lowest priority:

  1. -var on the CLI, terraform plan -var="env=prod". Overrides everything.
  2. -var-file on the CLI, terraform plan -var-file=prod.tfvars. When multiple -var-file flags are present, the last one wins.
  3. *.auto.tfvars and *.auto.tfvars.json, all files with this suffix in the project root are loaded automatically. They are processed in alphabetical order; the last one alphabetically wins on a collision.
  4. terraform.tfvars and terraform.tfvars.json, a fixed name, loaded automatically.
  5. TF_VAR_* environment variables, export TF_VAR_env=prod then terraform plan.
  6. default in the variable block. The lowest priority, a fallback.

If none of the above provides a value and there is no default, Terraform prompts interactively in the terminal.

Priority example

Suppose a variable is declared as:

hcl
variable "env" {
  type    = string
  default = "dev"
}

What Terraform sees in different situations:

SourcesValue of var.env
Nothing"dev" (from default)
export TF_VAR_env=staging"staging"
TF_VAR_env=staging + terraform.tfvars contains env = "prod""prod" (.tfvars overrides the env var)
All of the above + -var-file=temp.tfvars where env = "qa""qa"
All of the above + -var="env=hotfix""hotfix"

The rule is simple: closer to the CLI wins.

When to use each source

  • default, for values that rarely change and cover 90% of cases. AWS region, small instance type.
  • terraform.tfvars, the main values for the project. Often added to .gitignore because it may contain tokens and secrets.
  • *.auto.tfvars, per-environment configuration when you are not using -var-file. For example, dev.auto.tfvars loads automatically in the dev directory.
  • -var-file, for CI/CD: one HCL config, separate tfvars for dev/staging/prod. The file is selected by an environment variable or a flag.
  • -var, for one-off overrides. "Run plan once with a different value without touching any files."
  • TF_VAR_*, for CI: secrets that must not go into git. The CI system injects them as environment variables.

TF_VAR_*, specifics

The prefix TF_VAR_ followed by the variable name:

bash
export TF_VAR_env=prod
export TF_VAR_db_password="$(vault read -field=password kv/prod/db)"
terraform plan

For a variable of type string, number, or bool, the env value is used as-is. For type list or map, the env value must be JSON:

bash
export TF_VAR_tags='{"env": "prod", "team": "platform"}'
export TF_VAR_azs='["us-east-1a", "us-east-1b"]'

Case matters: TF_VAR_my_var is not the same as TF_VAR_MY_VAR.

auto.tfvars vs .tfvars, a subtle difference

terraform.tfvars is the only fixed name. *.auto.tfvars files can have any name with that suffix.

Why the split?

  • terraform.tfvars is the primary set; often added to .gitignore.
  • dev.auto.tfvars, staging.auto.tfvars, prod.auto.tfvars hold environment values and are usually committed. All of them load at once, so a single workspace should contain only the one you need.

An alternative approach: keep environment files in separate directories without the auto suffix, and pass them with -var-file=envs/prod.tfvars. This is simpler for CI.

Pitfalls

  • All *.auto.tfvars files load. If your project root has both dev.auto.tfvars and prod.auto.tfvars at the same time, both are read; the last one alphabetically wins. This is often not what you want.

  • terraform.tfvars in git is a common secret leak. If you store tokens there, add it to .gitignore. Do not rely on "nobody will look."

  • Do not pass secrets via -var. They end up in shell history. Use TF_VAR_* with read -s or pull them from a secrets manager.

  • JSON is required for complex types in env vars. If you declared type = list(string) and set TF_VAR_x=us-east-1, Terraform does not parse this as a list and will fail. You need TF_VAR_x='["us-east-1"]'.

  • Interactive input does not work in CI. If a pipeline forgets to pass a variable, Terraform will wait for keyboard input and the job will hang indefinitely. Fix this with -input=false, which makes Terraform fail with a clear error instead of waiting.

§ команды

bash
terraform plan -var='env=prod' -var='region=us-east-1'

Multiple -var flags: one variable per flag.

bash
terraform plan -var-file=envs/prod.tfvars

Load a variable file for a specific environment.

bash
TF_VAR_env=prod TF_VAR_region=us-east-1 terraform plan

Via environment variables. Convenient in CI: secrets arrive as environment variables.

bash
terraform plan -input=false

Disable interactive prompts. Required in CI.

§ см. также

  • tf-variableThe variable block: input to your configurationA variable is a parameter that receives its value from outside the configuration (CLI, environment variable, .tfvars file). You declare it in HCL with type, default, description, and validation, then reference it as var.name. Variables remove hardcoded values and let one HCL configuration serve multiple environments.
  • tf-tfvars.tfvars: variable value files.tfvars files hold variable values in HCL or JSON format. terraform.tfvars and *.auto.tfvars are loaded automatically; all others require -var-file. This is the main mechanism for separating code from environment configuration.
Footer
linuxlab-
Copyright © 2026 LinuxLab. All rights reserved.
Tutorials
Pricing
About
Privacy & cookies