100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
HCL

Secrets Management in Terraform

Learn how to keep API keys, passwords, and certificates out of your Terraform code and state, using dedicated secret stores and encryption strategies.

Terraform in ProductionIntermediate10 min readJul 9, 2026
Analogies

Secrets Management in Terraform

Terraform frequently needs sensitive values — database passwords, API tokens, TLS private keys, cloud access credentials — to provision infrastructure. The core tension is that Terraform's execution model persists nearly everything it touches: variable values, resource attributes, and computed outputs all end up in the plan file and, more importantly, in the state file. Unlike application secrets that can be injected at runtime and forgotten, Terraform secrets tend to have a much longer paper trail unless you deliberately design around it. Effective secrets management in Terraform is therefore not a single feature but a discipline that spans variable declaration, provider configuration, state storage, and CI/CD pipeline design.

🏏

Cricket analogy: Terraform persisting secrets across plan and state files is like a scorecard permanently recording a player's exact biometric data submitted for fitness testing — unlike a quick verbal fitness check, it leaves a lasting paper trail across the whole tournament record.

The sensitive Flag and Its Limits

Terraform lets you mark a variable or output as sensitive, which suppresses the value from CLI output in plans, applies, and console logs. This is a genuinely useful guardrail against accidental screen-sharing or CI log leakage, but it is a UI-layer redaction only — it does nothing to protect the value inside the state file, which stores it in plaintext by default. Treating the sensitive flag as encryption is one of the most common misconceptions among teams new to Terraform.

🏏

Cricket analogy: Marking a Terraform value sensitive is like a broadcaster blurring a player's private medical note on the TV graphic — it hides the value from the viewer's screen, but the raw document sitting in the production van's files is still fully readable.

hcl
variable "db_password" {
  type        = string
  sensitive   = true
  description = "Master password for the RDS instance"
}

resource "aws_db_instance" "primary" {
  identifier     = "app-primary-db"
  engine         = "postgres"
  engine_version = "15.4"
  instance_class = "db.t3.medium"
  username       = "app_admin"
  password       = var.db_password
  skip_final_snapshot = false
}

output "db_endpoint" {
  value     = aws_db_instance.primary.endpoint
  sensitive = false
}

Pulling Secrets from a Dedicated Secret Store

The preferred pattern is to never author secret literals in HCL or tfvars files at all. Instead, use a data source to fetch the secret at plan/apply time from a purpose-built secret manager such as AWS Secrets Manager, HashiCorp Vault, Azure Key Vault, or GCP Secret Manager. This keeps ownership of secret rotation and access policy with a system designed for it, and it means the secret's lifecycle is decoupled from your Terraform code's lifecycle — rotating a password does not require a code change or a re-apply of unrelated resources.

🏏

Cricket analogy: Fetching a secret from Vault at apply time instead of hardcoding it is like a team pulling the day's pitch report from the groundskeeper on match morning instead of printing it in last season's handbook — updating the pitch conditions never requires reprinting the whole handbook.

hcl
data "aws_secretsmanager_secret_version" "db" {
  secret_id = "prod/app/db-password"
}

resource "aws_db_instance" "primary" {
  identifier = "app-primary-db"
  username   = "app_admin"
  password   = data.aws_secretsmanager_secret_version.db.secret_string
  # ... other config
}

Protecting the State File Itself

Even when secrets are pulled from a vault rather than hardcoded, Terraform still writes the resolved value into state, because state must record the real-world attributes of every managed resource to compute future diffs. The mitigation is defense in depth at the backend layer: use a remote backend with encryption at rest (S3 with SSE-KMS, Azure Blob with a customer-managed key, Terraform Cloud's built-in encryption), restrict IAM/RBAC access to the state bucket or workspace to a small set of principals, and enable state file access logging so reads are auditable.

🏏

Cricket analogy: Even when a secret comes from Vault, Terraform still writes the resolved password into state, so teams add defense in depth like locking the team's confidential scouting reports in a safe (encryption at rest), restricting the safe's key to the coach and captain only (IAM), and logging every time it's opened (access logging).

Never commit a .tfvars file containing plaintext secrets to version control, even a private repository. Git history retains every commit forever unless you rewrite history and force-push, and a single leaked commit can expose a credential long after the file is 'fixed.' Add *.tfvars with secret content to .gitignore and use environment variables or a secret store instead.

A useful mental model: Terraform state is not a secrets vault — it is a receipt. It records what was purchased (provisioned) so Terraform can reconcile future changes, but a receipt was never designed to be the secure custody location for the item itself.

  • The sensitive attribute hides values from CLI/log output but does not encrypt them in the state file.
  • Prefer pulling secrets at apply time via data sources from Vault, AWS/Azure/GCP secret managers rather than hardcoding them in HCL.
  • Always store remote state in a backend with encryption at rest and strict access controls.
  • Never commit plaintext secrets in .tfvars files to version control.
  • Enable audit logging on the state backend so secret exposure via state reads is traceable.
  • Rotate secrets in the secret store independently of Terraform code changes to reduce blast radius.

Practice what you learned

Was this page helpful?

Topics covered

#HCL#TerraformInfrastructureAsCodeStudyNotes#DevOps#SecretsManagementInTerraform#Secrets#Management#Terraform#Sensitive#StudyNotes#SkillVeris