secrets in Terraform. How it handles. project.
Source: Dev.to
Project 1 — AWS Secrets Manager
Scenario
- Company types: Mid‑large, SaaS, FinTech, E‑commerce, Healthcare (e.g., customer data with SOC2, HIPAA, PCI compliance).
- Application: Uses RDS (MySQL/Postgres).
- Requirements:
- Password must not be in Git or visible to developers.
- Must be rotatable.
- Only IAM‑authorized services can access it.
Desired outcome
Create an RDS database without hard‑coding the password. Terraform should:
- Read the password securely at runtime.
- Never store it in code.
- Allow access only to IAM‑authorized services.
aws secretsmanager create-secret \
--name prod/rds/db_password \
--secret-string '{"password":"StrongProdPass123!"}'
Note: The secret is created outside Terraform.
Terraform Backend Configuration
terraform {
backend "s3" {
bucket = "terraform-state-prod"
key = "rds/terraform.tfstate"
region = "us-east-1"
dynamodb_table = "terraform-locks"
encrypt = true
}
}
- Encrypts state.
- Prevents state corruption.
- Enables team‑safe deployments.
Reading the secret in Terraform
data "aws_secretsmanager_secret" "db" {
name = "prod/rds/db_password"
}
data "aws_secretsmanager_secret_version" "db" {
secret_id = data.aws_secretsmanager_secret.db.id
}
Terraform does not create the secret; it only reads it.
RDS Instance Resource
resource "aws_db_instance" "prod" {
engine = "mysql"
instance_class = "db.t3.micro"
username = "admin"
password = jsondecode(
data.aws_secretsmanager_secret_version.db.secret_string
)["password"]
}
- Supports password rotation.
- Auditing via IAM.
- Meets security compliance.
- Zero secret exposure in Git.
In production, database passwords are stored in AWS Secrets Manager. Terraform reads them at runtime using IAM permissions, avoiding hard‑coded secrets and supporting rotation and compliance.
Scenario: Simple EC2 Secrets (SSM Parameter Store)
Goal
Securely pass secrets to EC2 instances without exposing them.
aws ssm put-parameter \
--name /prod/app/api_key \
--type SecureString \
--value "api-key-123"
Create an IAM role with ssm:GetParameter permission and attach it to the EC2 instance.
data "aws_ssm_parameter" "api_key" {
name = "/prod/app/api_key"
with_decryption = true
}
EC2 user‑data example
# For simple secrets, we use SSM SecureString. EC2 IAM roles allow secure access without exposing secrets in scripts or repositories.
CI‑Driven Secret Injection
Context
- Modern DevOps, remote teams, platform engineering.
- Terraform runs in CI; developers must not have AWS keys locally.
Example
variable "db_password" {
sensitive = true
}
CI environment variables (e.g., GitHub Actions):
env:
TF_VAR_db_password: ${{ secrets.DB_PASSWORD }}
- No local secrets.
- Zero‑trust model.
- Audit logs and consistent deployments.
Terraform runs only in CI pipelines. Secrets are injected at runtime from the CI secret manager, preventing local exposure.
Centralized Terraform Execution (Terraform Cloud)
- Centralizes execution and stores sensitive variables encrypted.
- Provides state locking, encrypted storage, and remote runs.
- Eliminates local Terraform installations for team members.
Terraform Cloud centralizes execution and securely stores sensitive variables, making collaboration safe.
Dynamic Secrets with Vault
- Ideal for high‑security environments (banks, FinTech, enterprises).
- Vault issues short‑lived DB credentials.
- Terraform reads the dynamic credentials; they auto‑expire.
Vault provides dynamic secrets, reducing blast radius by issuing time‑bound credentials.
Tool Summary
| Tool | Typical Use Case |
|---|---|
| AWS Secrets Manager | Production databases (high‑value secrets) |
| AWS SSM Parameter Store | Simple EC2 secrets (SecureString) |
| CI secret stores | Pipeline‑level secret injection |
| Terraform Cloud | Centralized team execution |
| HashiCorp Vault | High‑security, dynamic secret generation |