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-account✅Limited
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?