Sensitive data visible in plan output
terraform plan output shows plaintext passwords or API keys
Focused incident mode — strips away everything but this runbook.
Symptoms
- terraform plan output shows plaintext passwords or API keys
- Terraform outputs display sensitive values in CI logs
- State file contains unencrypted secrets
Never log terraform plan to CI stdout without masking. Use terraform plan -json and filter sensitive values in the pipeline.
Evidence to grab
Collect these artifacts before you change anything — they prove (or rule out) each cause.
Plan output with secrets
terraform plan 2>&1 | grep -iE 'password|secret|key|token'Output declarations
grep -n 'sensitive' outputs.tf
Diagnostic flow
Run the steps in order, marking each claim confirmed or refuted. The evidence you gather feeds the ranked causes below.
Guided decision tree is ready.
Steps with commands, expected output, and pass/fail branches.
Ranked root causes
Evidence checklist
- outputs.tf does not have sensitive = true
- terraform plan shows the value in plaintext
Confirm before fixing
grep -n 'sensitive' outputs.tfCheck for sensitive flag
Fix
sed -i '/output ".*"/a\ sensitive = true' outputs.tfMark outputs as sensitive
Resolution runbook
Apply from top to bottom after the cause is confirmed. Review every command before running it — risk tags are shown on each.
grep -n 'sensitive' outputs.tfCheck which outputs are protected
terraform plan 2>&1 | grep -iE 'password|secret|key|token'Scan plan for leaked secrets
terraform output -json | jq 'to_entries[] | select(.value.sensitive==true) | .key'List sensitive outputs
terraform state pull | grep -iE 'password|secret|key|token'Scan state for plaintext secrets
Prevention
- Mark ALL outputs containing secrets with sensitive = true.
- Use terraform cloud or vault for secret storage instead of variables.
- Enable state encryption at rest (S3 SSE, GCS CMEK).
- Mask terraform output in CI logs using pipeline-specific secret detection.
Related runbooks
Same stack, same failure family — worth a skim.
terraform plan shows everything will be created (no existing resources in state)
Error: Error loading state: SyntaxError: JSON input
Commands marked READ CHANGE DESTRUCTIVE — never run DESTRUCTIVE commands against production data you cannot restore. Copy → verify → execute.