Terraform Advanced — Secrets Management

1 minute read

Keep sensitive values out of your Terraform code and state.


The Problem

# ❌ Anti-pattern: hardcoded secrets
resource "aws_db_instance" "main" {
  username = "admin"
  password = "SuperSecret123!"  # Visible in state file!
}

Even if you use a variable, the value is stored in plain text in state.


Strategy 1 — Environment Variables

export TF_VAR_db_password="$(aws secretsmanager get-secret-value \
  --secret-id prod/db --query SecretString --output text)"

terraform apply
variable "db_password" {
  type      = string
  sensitive = true  # Hides from plan output
}

Strategy 2 — AWS Secrets Manager Data Source

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

resource "aws_db_instance" "main" {
  username = "admin"
  password = data.aws_secretsmanager_secret_version.db.secret_string
}

⚠️ Warning: The secret value is still stored in state. Always encrypt your state backend.


Strategy 3 — Generate and Store

resource "random_password" "db" {
  length  = 32
  special = true
}

resource "aws_secretsmanager_secret_version" "db" {
  secret_id     = aws_secretsmanager_secret.db.id
  secret_string = random_password.db.result
}

resource "aws_db_instance" "main" {
  password = random_password.db.result
}

Sensitive Attribute

output "db_password" {
  value     = random_password.db.result
  sensitive = true  # terraform output won't show it
}

💡 Production Tip: Mark all secret variables and outputs as sensitive = true. This prevents accidental exposure in plan output and logs.


What’s Next?

Dynamic secrets with HashiCorp Vault.

← Security Vault Provider →

Updated: