HashiCorp Certified: Terraform Associate
Variables vs locals vs outputs for Terraform Associate
A variable block is an input that users or a calling module set, read as var.NAME. A locals block names an expression inside one module, read as local.NAME, and nothing outside the module can set it. An output block exposes a value: a child module's outputs reach the parent as module.NAME.OUTPUT, and root module outputs are shown after apply.
Input variables
A variable block declares an input, with optional type, description, default and validation. If a variable has no default and no value is given, Terraform prompts for it before it plans.
In the root module, users set values from the command line, files, environment variables or HCP Terraform. In a child module, the parent sets them as arguments in the module block.
sensitive = true hides the value in CLI output, but Terraform still stores it in state. ephemeral keeps a variable out of state and plan files, with limits on what you can assign to it.
Which value wins
When the root module gets several values for one variable, Terraform uses this order, highest first: -var and -var-file on the command line (in the order given) and HCP Terraform variables; *.auto.tfvars or *.auto.tfvars.json files in lexical order; terraform.tfvars.json; terraform.tfvars; TF_VAR_ environment variables; the variable's default.
Terraform loads only these files automatically: terraform.tfvars, terraform.tfvars.json, and names ending in .auto.tfvars or .auto.tfvars.json. A file named prod.tfvars is read only when you pass -var-file=prod.tfvars. A file named prod.auto.tfvars loads on a plain terraform plan.
Undeclared values are treated differently by source. Environment variables with no matching variable block are ignored. A file that sets an undeclared variable gives a warning. -var for an undeclared variable is an error.
Local values
A locals block gives a name to an expression, such as resource_name = "${var.project_name}-${var.environment}". It can use variables, resource attributes, function results and other locals. You declare them in a locals block but reference them with the singular local., as in local.resource_name.
Locals are visible only in the module that defines them. To give one to a child module, pass it as an argument in the module block.
HashiCorp suggests locals for a value used in many places, or for the result of a complex expression. Too many locals make it harder to see where a value comes from.
Outputs
An output block has a value and optional description and sensitive. Outputs let a child module pass values to its parent, show root module values after apply, let other configurations read root outputs through terraform_remote_state, and hand values to automation.
A sensitive output shows as <sensitive> in normal CLI output, but the value is stored in state, and terraform output -json or -raw prints it in plain text.
Where the exam catches people
- Believing any
.tfvarsfile loads automatically: onlyterraform.tfvars,terraform.tfvars.jsonand*.auto.tfvars(.json)do. Others need-var-file. - Believing a
TF_VAR_environment variable beatsterraform.tfvars: environment variables rank below every variable definition file. Only the default ranks lower. - Believing a child module can read the parent's
local.x: locals are visible only in their own module. Pass the value as a module argument. - Believing
sensitive = truekeeps a value out of state: it only hides the value in CLI output. The value is still stored in state. - Believing locals are referenced as
locals.NAME: the block islocals, but the reference islocal.NAME.