How to Handle Secrets in Terraform Without Hardcoding Them
Hardcoding secrets like passwords, API keys, or tokens directly in .tf files is a critical security mistake. This guide covers the right ways to manage secrets in Terraform.
What NOT to Do
# NEVER do this — secrets committed to version control
resource "aws_db_instance" "main" {
username = "admin"
password = "SuperSecretPassword123!" # BAD
}
Option 1: Environment Variables with TF_VAR_
Terraform reads environment variables prefixed with TF_VAR_ and maps them to input variables.
# In your shell or CI/CD pipeline
export TF_VAR_db_password="SuperSecretPassword123!"
# In variables.tf
variable "db_password" {
type = string
sensitive = true
}
# In main.tf
resource "aws_db_instance" "main" {
username = "admin"
password = var.db_password
}
Option 2: Mark Variables as sensitive
variable "api_key" {
type = string
sensitive = true # Masks value in CLI output and logs
}
Note: This masks the value in terminal output but does NOT encrypt it in the state file.
Option 3: HashiCorp Vault (Most Secure)
provider "vault" {
address = "https://vault.mycompany.com"
}
data "vault_generic_secret" "db_creds" {
path = "secret/database/prod"
}
resource "aws_db_instance" "main" {
username = data.vault_generic_secret.db_creds.data["username"]
password = data.vault_generic_secret.db_creds.data["password"]
}
Option 4: AWS Secrets Manager
data "aws_secretsmanager_secret_version" "db_pass" {
secret_id = "prod/app/db_password"
}
resource "aws_db_instance" "main" {
password = data.aws_secretsmanager_secret_version.db_pass.secret_string
}
Option 5: .tfvars Files (Keep Out of Git)
# terraform.tfvars — ADD THIS TO .gitignore
db_password = "SuperSecretPassword123!"
# .gitignore
*.tfvars
*.tfvars.json
Key Takeaway
Never store secrets in .tf files or commit them to version control. Use TF_VAR_ environment variables for simple cases, and HashiCorp Vault or cloud-native secret managers (AWS Secrets Manager, Azure Key Vault) for production workloads.
(Visited 32 times, 1 visits today)