TERRAFORM-SECURITY
Authorized use only. Offensive reference for systems you own or are explicitly permitted to test. You are responsible for staying within the law.
OVERVIEW#
Terraform provisions infrastructure as code (IaC). Security risks center on state files (which contain secrets in plaintext), insecure resource defaults, drift, and unpinned modules/providers. This sheet covers state hygiene, static scanning, and secret handling.
STATE FILE RISKS#
terraform state list # List managed resources terraform state show <resource> # Show one resource (may leak secrets) terraform state pull > state.json # Pull remote state locally # State stores secrets in PLAINTEXT (passwords, keys, tokens) # NEVER commit *.tfstate or *.tfstate.backup to git grep -Ei 'password|secret|token|key' terraform.tfstate
STATE HARDENING#
# Use encrypted remote backend, not local state:
# backend "s3" { encrypt = true, kms_key_id = "...",
# dynamodb_table = "<lock-table>" }
# Enable state locking to prevent concurrent corruption
# Restrict backend bucket/container to least-privilege IAM
# Enable versioning on the state bucket for rollback
STATIC SCANNING - CHECKOV#
checkov -d . # Scan a directory checkov -f main.tf # Scan a single file checkov -d . --compact # Condensed output checkov -d . -o json > cov.json # JSON output checkov -d . --framework terraform # Limit to TF checkov -d . --skip-check CKV_AWS_20 # Skip a specific check checkov -d . --soft-fail # Report without failing CI
STATIC SCANNING - TFSEC / TRIVY#
tfsec . # Scan current dir (legacy) tfsec . --format json # JSON output trivy config . # Trivy IaC scan (tfsec merged in) trivy config --severity HIGH,CRITICAL . trivy config . --exit-code 1 # Fail CI on findings
STATIC SCANNING - TERRASCAN / KICS#
terrascan scan -i terraform # Policy-as-code scan terrascan scan -t aws # Cloud-specific policies kics scan -p . -o results # KICS multi-IaC scanner
PLAN & DRIFT REVIEW#
terraform plan -out=tf.plan # Save plan for review terraform show -json tf.plan > p.json# Machine-readable plan terraform plan -detailed-exitcode # Exit 2 = drift detected terraform refresh # Reconcile state with real infra checkov -f tf.plan # Scan the PLAN, not just source
SECRET MANAGEMENT#
# Do NOT hardcode secrets in .tf or .tfvars
# Pull from a vault at plan/apply time instead:
# data "vault_generic_secret" "x" { path = "secret/app" }
# Or environment: TF_VAR_db_password
# Mark variables sensitive to redact from CLI output:
# variable "db_password" { sensitive = true }
git secrets --scan # Pre-commit secret scan
trufflehog filesystem . # Deep secret discovery
SUPPLY CHAIN#
# Pin provider + module versions to prevent drift/tampering:
# required_providers { aws = { version = "= 5.42.0" } }
# module "x" { source = "...//mod?ref=v1.2.3" }
terraform providers # Show provider tree
terraform providers lock # Generate .terraform.lock.hcl
terraform init -upgrade # Controlled provider upgrade
EXAMPLES#
# CI gate: fail build on HIGH/CRITICAL IaC misconfig trivy config --exit-code 1 --severity HIGH,CRITICAL . # Scan the actual plan to catch runtime-resolved values terraform plan -out=tf.plan && terraform show -json tf.plan > p.json checkov -f p.json # Confirm no secrets leaked into committed state git log --all --full-history -- '*.tfstate' # Detect infrastructure drift in a pipeline terraform plan -detailed-exitcode || echo "Drift or changes present"
NOTES#
- The state file is the crown jewel: encrypt, lock, restrict, version - Scan the PLAN output, not only .tf source - many values (secrets, computed ARNs) only appear after resolution - checkov + trivy config cover overlapping but not identical checks; run both in CI for FS-grade coverage - Map IaC findings to DORA ICT risk management and CSSF cloud outsourcing expectations for LU financial clients - .terraform.lock.hcl should be committed; *.tfstate should not