Lesson 17 / 25

Sensitive Values

Hide secrets from output.

sensitive = true and its limits

Mark variables and outputs that hold secrets as sensitive = true: Terraform then redacts them in plan and output (<sensitive>). Values derived from sensitive data are also sensitive, and Terraform refuses to expose them in a root module output unless you mark it sensitive, a guard against accidental leaks. If a derived value is genuinely safe (such as a length), nonsensitive() declares that explicitly. terraform output -raw still prints the real value for scripts.

Protect data and critical resources

Sensitive values, state protection and lifecycle rules prevent leaks and accidental destruction.

Three ideas: sensitive values, secrets in state, prevent_destroy.
Figure 6.1 — Sensitive values, state and prevent_destroy.

An output that leaks a secret is rejected, run

I ran this with Terraform 1.16.4 and the hashicorp/local 2.9.1 and hashicorp/random 3.9.1 providers, which manage local files and random values, so no cloud account was needed; each example starts from a fresh directory. An output that returns the length of a generated password without being marked sensitive fails plan with "Output refers to sensitive values" and a suggestion to add sensitive = true.

terraform plan -no-color 2>&1 | grep -E "Error|refers to sensitive|sensitive = true"

Output:

Error: Output refers to sensitive values
    sensitive = true

Redacted output and what the state holds, run

I ran this with Terraform 1.16.4 and the hashicorp/local 2.9.1 and hashicorp/random 3.9.1 providers, which manage local files and random values, so no cloud account was needed; each example starts from a fresh directory. terraform output shows db_password as and the deliberately non-sensitive length as 20; -raw still returns the 20-character value; and jq finds the full 20-character password in plain text in terraform.tfstate.

terraform output -no-color
terraform output -no-color -raw db_password | wc -c
jq -r '.resources[] | select(.type == "random_password") | .instances[0].attributes.result | length' terraform.tfstate

Output:

db_password = <sensitive>
password_length = 20
20
20

Quick check: Does marking an output sensitive keep the value out of the state file?

  • Yes, it is encrypted automatically in local state
  • Yes, it is removed from state
  • No, state still stores it in plain text, so the state must be protected
  • Sensitive values are never generated
Answer

No, state still stores it in plain text, so the state must be protected — Redaction is not encryption.