Table of Contents
The Problem With Secrets in Terraform
Terraform state files contain sensitive data in plain text. API keys, database passwords, and certificates stored in state are readable by anyone with state access. Here’s how to handle this securely.
Rule 1: Never Hardcode Secrets
# BAD - secret in code
resource "aws_db_instance" "db" {
password = "super-secret-password" # This ends up in state AND git
}
# GOOD - use a variable
resource "aws_db_instance" "db" {
password = var.db_password
}
Method 1: Environment Variables
export TF_VAR_db_password="super-secret-password"
terraform apply
Method 2: AWS Secrets Manager
data "aws_secretsmanager_secret_version" "db_password" {
secret_id = "prod/database/password"
}
resource "aws_db_instance" "db" {
password = data.aws_secretsmanager_secret_version.db_password.secret_string
}
Method 3: HashiCorp Vault
provider "vault" {
address = "https://vault.example.com"
}
data "vault_generic_secret" "db" {
path = "secret/data/prod/database"
}
resource "aws_db_instance" "db" {
password = data.vault_generic_secret.db.data["password"]
}
Method 4: SOPS Encrypted Files
# Encrypt a tfvars file
sops --encrypt --in-place secrets.tfvars
# Decrypt and apply
sops -d secrets.tfvars | terraform apply -var-file=/dev/stdin
Marking Outputs as Sensitive
output "db_connection_string" {
value = "postgresql://${var.db_user}:${var.db_password}@${aws_db_instance.db.endpoint}"
sensitive = true
}
variable "db_password" {
type = string
sensitive = true # Prevents value from showing in plan output
}
State File Security
Even with these methods, sensitive values still exist in state. Protect state by:
- Encrypting state at rest — enable S3 SSE or use encrypted backends
- Restricting state access — IAM policies limiting who can read state
- Using Terraform Cloud — state is encrypted and access-controlled
- Never committing state to git — add
*.tfstateto.gitignore
Best Practices Summary
- Never hardcode secrets in
.tffiles - Use a secrets manager (AWS SM, Vault, Azure Key Vault)
- Mark sensitive variables and outputs with
sensitive = true - Encrypt state at rest and restrict access
- Rotate secrets regularly
- Use short-lived credentials (OIDC, STS) where possible
Learn More
- Terraform for Beginners Course — hands-on security labs
- Terraform By Example Book — real-world patterns
- Terraform Cheat Sheet — quick command reference


