Skip to main content

Module 15, Secrets Management

Why Variables Aren't Enough

# WRONG, the password ends up in terraform.tfstate in plaintext
variable "db_password" {
default = "SecurePass123!"
}

Anyone with access to the state file has your database password. State is often stored in S3 where access may be broader than intended.

AWS Secrets Manager

resource "aws_secretsmanager_secret" "db_password" {
name = "${var.app_name}/db-password"
recovery_window_in_days = 0 # immediate deletion (dev only; use 7+ for prod)
}

resource "aws_secretsmanager_secret_version" "db_password" {
secret_id = aws_secretsmanager_secret.db_password.id
secret_string = var.db_password
}

# Use AWS-managed rotation to avoid storing password in state entirely
resource "aws_db_instance" "main" {
manage_master_user_password = true # AWS handles rotation automatically
lifecycle { ignore_changes = [password] }
}

AWS Parameter Store

Cheaper than Secrets Manager for non-rotating config values:

resource "aws_ssm_parameter" "jwt_secret" {
name = "/${var.app_name}/${var.environment}/jwt-secret"
type = "SecureString" # KMS-encrypted
value = var.jwt_secret
}

# Read in application at runtime
data "aws_ssm_parameter" "jwt_secret" {
name = "/${var.app_name}/${var.environment}/jwt-secret"
with_decryption = true
}

Secrets Manager vs Parameter Store

FeatureSecrets ManagerParameter Store
Cost~$0.40/secret/monthFree (Standard tier)
Automatic rotation✅ Built-in❌ Manual
Versioning
Cross-accountLimited
Best forDB passwords, API keysConfig values, feature flags

Knowledge Check

  1. Why does storing passwords in Terraform variables not fully solve the secrets problem?
  2. What is the difference between Secrets Manager and Parameter Store?
  3. What does manage_master_user_password = true do on an RDS instance?
  4. How would you rotate a secret automatically?
  5. Why use SecureString type in Parameter Store?