Terraform Security: Secrets, Policies & Sentinel
Terraform security encompasses secrets management, policy enforcement, IAM least-privilege, and misconfiguration scanning to ensure infrastructure is deployed securely and complies with organizational standards.
What You'll Learn
In this tutorial, you will learn how to manage Terraform secrets securely, enforce policies with Sentinel, scan for security misconfigurations, and implement least-privilege IAM for Terraform operations.
Why It Matters
Infrastructure misconfigurations cause most cloud data breaches. Hardcoded secrets, public S3 buckets, and over-permissive IAM roles are common findings in security audits. Terraform security practices prevent these vulnerabilities from reaching production.
Real-World Use
DodaTech uses HashiCorp Vault for dynamic database credentials in Terraform. Durga Antivirus Pro Sentinel policies enforce encryption, logging, and network restrictions across all Terraform deployments, maintaining compliance with SOC 2 and GDPR requirements.
Secrets Management
Environment Variables
Never hardcode secrets in Terraform files. Use environment variables:
export TF_VAR_db_password="my-secure-password"
export TF_VAR_db_username="admin"
variable "db_password" {
description = "Database master password"
type = string
sensitive = true
}
Expected output: Terraform reads TF_VAR_db_password from the environment. The variable is marked sensitive and does not appear in logs or plan output.
HashiCorp Vault
data "vault_aws_access_credentials" "creds" {
backend = "aws"
role = "terraform"
}
provider "aws" {
region = "us-east-1"
access_key = data.vault_aws_access_credentials.creds.access_key
secret_key = data.vault_aws_access_credentials.creds.secret_key
}
Expected output: Vault generates temporary AWS credentials valid for a configurable duration. Terraform uses these credentials, which are automatically revoked after the TTL expires.
Terraform Cloud Variables
Store sensitive variables in Terraform Cloud as sensitive variables. They are encrypted at rest and never displayed in the UI or API responses.
Policy as Code with Sentinel
Sentinel is a policy-as-code framework. Policies enforce rules before Terraform creates resources:
import "tfplan"
s3_buckets = filter tfplan.resource_changes as _, rc in {
rc.mode is "managed" and rc.type is "aws_s3_bucket"
}
main = rule {
all s3_buckets as _, bucket {
bucket.applied.server_side_encryption_configuration is not null
}
}
Expected output: This policy requires all S3 buckets to have encryption configured. If any bucket lacks encryption, Terraform Cloud blocks the apply.
Enforcing Tags
import "tfplan"
required_tags = ["Environment", "ManagedBy", "CostCenter"]
all_resources = filter tfplan.resource_changes as _, rc in {
rc.mode is "managed"
}
main = rule {
all all_resources as _, resource {
all required_tags as _, tag {
resource.applied.tags contains tag
}
}
}
Expected output: Every new or modified resource must have Environment, ManagedBy, and CostCenter tags. Violations appear as hard-mandatory failures in Terraform Cloud runs.
IAM Least Privilege
Minimum Permissions for Terraform
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["ec2:Describe*", "ec2:CreateSecurityGroup"],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": ["s3:ListBucket", "s3:GetObject", "s3:PutObject"],
"Resource": ["arn:aws:s3:::dodatech-terraform-state", "arn:aws:s3:::dodatech-terraform-state/*"]
}
]
}
Expected output: Terraform assumes a role with only the permissions needed for its managed resources. Unused services are denied.
Dynamic Provider Credentials
provider "aws" {
assume_role {
role_arn = "arn:aws:iam::123456789012:role/TerraformRole"
session_name = "TerraformSession"
duration = "1h"
}
}
Expected output: Terraform assumes the TerraformRole for each operation. The role has scoped permissions, and the session expires after one hour.
Misconfiguration Scanning
TFSec in Pipeline
- name: TFSec Security Scan
run: tfsec --format sarif --output tfsec.sarif .
- name: Upload TFSec Results
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: tfsec.sarif
Expected output: TFSec scans for 150+ security misconfigurations including unencrypted storage, open security groups, and missing logging.
Common Mistakes
1. Hardcoding Secrets in tfvars
Committing terraform.tfvars with passwords or API keys exposes secrets in version control. Use .gitignore for sensitive files.
2. Overly Permissive IAM Roles
Using AdministratorAccess for Terraform violates least privilege. Scope roles to only the resources Terraform manages.
3. Ignoring Sentinel Warnings
Sentinel soft-mandatory policies warn about issues. Treat all warnings as failures to prevent configuration drift.
4. Storing State Without Encryption
State files contain resource IDs and metadata. Always enable encryption on backend storage.
5. Not Rotating Provider Credentials
Long-lived access keys increase blast radius. Use Vault dynamic credentials or OIDC for short-lived authentication.
Practice Questions
1. How do you pass secrets to Terraform without storing them in files? Use environment variables with the TF_VAR_ prefix, Vault data sources, or Terraform Cloud sensitive variables.
2. What is Sentinel and how does it enforce security? Sentinel is a policy-as-code framework that runs in Terraform Cloud, enforcing rules like required encryption and tags.
3. What is the principle of least privilege in Terraform IAM? Terraform should assume a role with permissions limited to only the resources and actions it needs.
4. How does Vault integrate with Terraform for secrets? Vault data sources retrieve dynamic, temporary credentials that Terraform uses and that expire automatically.
5. Challenge: Create a Sentinel policy that requires all EC2 instances to have encryption-enabled EBS volumes and a Name tag. Test it with a non-compliant configuration.
Mini Project: Secure Terraform Pipeline
Create a Terraform configuration that uses Vault for database credentials, implements a least-privilege IAM role, adds TFSec scanning to a GitHub Actions workflow, and enforces tagging with a Sentinel-style policy check.
Related Concepts
What's Next
Secure your Terraform deployments with secrets management and policy enforcement, then extend to Multi-Cloud Architectures across AWS, Azure, and GCP.
Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro