Keep secret values out of committed tfvars files, and remember that Terraform still stores sensitive variables in state. HashiCorp says to ignore variable files with sensitive values in version control, and offers an ephemeral argument that omits a variable from state and plan files, with restrictions.
Which files load by themselves
Terraform's variable documentation says it automatically loads variable definition files named terraform.tfvars, terraform.tfvars.json, or ending in .auto.tfvars or .auto.tfvars.json. You can also pass a file explicitly with -var-file. The page says that if a variable definition file contains any sensitive values, you should make sure your version control provider ignores those files.
The practical consequence: a file called terraform.tfvars in your working directory is picked up without any flag, so it is easy to leave a secret in it and forget it exists.
Environment variables as an alternative
Terraform reads environment variables with the TF_VAR_ prefix, for example TF_VAR_environment. The documentation says environment variables are useful in CI/CD pipelines when you want to inject values without creating more files. For complex values it advises proper JSON syntax and recommends variable definition files for readability and to avoid shell escaping.
An environment variable avoids a file on disk, but it can land in shell history if you type it, so load it from a secure source rather than pasting.
What sensitive true does and does not do
Marking a variable sensitive = true hides its value in plan output. The documentation is clear that Terraform still stores the values of sensitive variables in your state. So anyone who can read the state can read the secret.
The same page says you can add the ephemeral argument to a variable to omit it from state and plan files. It warns that ephemeral adds restrictions on the values you can assign, so check how it fits your configuration before relying on it.
| Mechanism | Hidden in plan output | Kept out of state |
|---|---|---|
| sensitive = true | Yes | No |
| ephemeral | Per HashiCorp, omitted from state and plan files | Yes, with restrictions |
| TF_VAR environment variable | Not by itself | No, unless combined with ephemeral |
A tidy local setup
- Add
*.tfvarsand*.auto.tfvarsto your ignore file, and commit aexample.tfvarswith placeholder values. - Keep production values in your CI system's secret store.
- Store state in a remote backend with encryption and tight access, since state can hold secrets.
- Prefer data sources or short-lived credentials from your cloud identity over long-lived keys in variables.
- Review pull requests for new variable files.
Check what you have today
Search your repositories for committed tfvars files and open any you find. Look at your state storage location and who can read it. If a real secret was ever in a committed file, rotate it, because ignoring the file now does not remove the earlier commit.
Where Safeguard fits
Safeguard works on the dependency and code side of your software: SBOM and dependency scanning, reachability analysis and policy gates. It does not store or manage credentials, so keep using your password manager, secrets manager or cloud identity for that. You can run a free scan of a project at gold.safeguard.sh/scan.
Quick check
Does Terraform load every .tfvars file?
It loads the specific names the documentation lists. Other names need the -var-file flag.
Is a sensitive variable encrypted in state?
The documentation only says Terraform still stores sensitive values in state. Protect the state itself.
What is ephemeral for?
It omits a variable from state and plan files, with restrictions on the values you can assign.
Sources
Last reviewed: 19 October 2026.