TerraformPilot

Guides

How to Manage Secrets and Sensitive Data in Terraform

Best practices for managing secrets, passwords, and sensitive data in Terraform configurations. Step-by-step guide with code examples and best practices for ...

LLuca Berton1 min read

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:

  1. Encrypting state at rest — enable S3 SSE or use encrypted backends
  2. Restricting state access — IAM policies limiting who can read state
  3. Using Terraform Cloud — state is encrypted and access-controlled
  4. Never committing state to git — add *.tfstate to .gitignore

Best Practices Summary

#
  1. Never hardcode secrets in .tf files
  2. Use a secrets manager (AWS SM, Vault, Azure Key Vault)
  3. Mark sensitive variables and outputs with sensitive = true
  4. Encrypt state at rest and restrict access
  5. Rotate secrets regularly
  6. Use short-lived credentials (OIDC, STS) where possible

Learn More

#
#secrets#sensitive#security#vault

Share this article