Skip to main content
In the previous lecture we looked at where secrets can leak in Terraform: state files, CLI output, logs, and version control. This article shows practical steps you can apply immediately to reduce that risk across three complementary layers:
  • Sensitive variables — hide values from CLI output and plans (fast, low-effort).
  • Environment variables — keep secrets out of version control and CI logs.
  • External secret stores — production-grade secret management and rotation.
These techniques are often combined in real projects to provide layered protection.
A presentation slide titled "Protecting Secrets in Your Configuration" showing three purple panels about Sensitive Variables, Environment Variables, and External Secret Sources. Each panel gives a short recommendation (hide values in outputs/logs; keep secrets out of version control; don't store secrets in Terraform).

Overview: When and why to use each technique

1) Sensitive variables

Terraform lets you mark variable and output declarations with sensitive = true. This prevents Terraform from printing the secret in most CLI outputs and replaces the value with a placeholder in plan/apply. Example variable declaration (variables.tf):
Use the variable in resources as usual:
If you must expose the secret via outputs, mark the output sensitive as well:
Typical plan/apply will show:
Notes and important caveats:
  • sensitive hides values from CLI output but does not remove them from the Terraform state file. You must secure your state backend (encryption, access controls, remote backends).
  • Don’t render sensitive values into templates, logs, or monitoring metrics that intentionally print values.
  • Avoid terraform console or other debugging tools to dump sensitive values in shared environments.
Marking a variable as sensitive hides its value from CLI outputs, but it does not remove the value from the Terraform state. Protect your state backend (enable encryption, restrict access, and use remote backends) to prevent leakage.

2) Environment variables

Passing secrets via environment variables keeps them out of committed files and supports secure injection from CI/CD platforms.
  • Terraform variables: prefix with TF_VAR_ (for example, TF_VAR_db_password becomes var.db_password).
  • Provider credentials: use provider-specific environment variables (e.g., AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, GOOGLE_CREDENTIALS).
Example (Bash):
Best practices:
  • Never commit export statements that contain secrets. Keep local export files (e.g., secrets.env) out of Git by adding them to .gitignore.
  • Don’t pass secrets on the command line using -var 'password=...' — shell history and process listings can expose them.
  • In CI, use the platform’s secret management (GitHub Actions secrets, GitLab CI variables, etc.) and avoid printing the values in logs.

3) External secret stores

For production systems, prefer dedicated secret managers that provide audit logs, rotation, and fine-grained access control. Common services:
  • HashiCorp Vault — dynamic secrets and strong ACLs.
  • AWS Secrets Manager / AWS SSM Parameter Store.
  • Azure Key Vault.
  • Google Secret Manager.
Pattern: fetch the secret at plan/apply time via a data source, decode it, and pass it into resources or pass a provider-side secret reference when supported. AWS Secrets Manager example:
Use local.db_password with resources, and mark any outputs that expose it as sensitive:
HashiCorp Vault example:
Important considerations:
  • Terraform fetching a secret at plan/apply time still risks storing that value in state if you put the raw secret into a resource attribute. Prefer provider-side secret references or server-side injection when available.
  • Limit Terraform’s permissions to the minimal read-only access needed for secrets and favor short-lived credentials.
  • Secure and audit access to the secret store itself.
Using external secret stores gives you centralized management and auditability. Combine them with Terraform sensitive declarations and a secure remote state backend to minimize secret exposure.

Summary Checklist

  • Mark secrets as sensitive in variables and outputs to reduce accidental exposure.
  • Use environment variables (in developer shells or CI secret stores) instead of committing secrets to files.
  • Use external secret stores (Vault, AWS Secrets Manager, etc.) for production: enable rotation and auditing.
  • Protect Terraform state: use remote backends, enable encryption at rest, and apply strict IAM policies.
  • Avoid passing secrets on the CLI or embedding them in logs, templates, or monitoring outputs.
By combining sensitive declarations, environment variable injection, and external secret stores, you can significantly reduce accidental leakage while keeping secrets as first-class runtime inputs.

Watch Video