Purpose
Enforce Terraform code quality and security standards across the terraform/ directory through automated checks.
What it checks (9 checks):
- •Hardcoded secrets (passwords, API keys, AWS keys, GitHub PATs) - HIGH
- •Security issues (RBAC wildcards, open security groups, encryption, public access) - HIGH
- •Missing version constraints (providers, modules, git refs) - HIGH
- •Resource lifecycle (prevent_destroy, Helm timeouts, deletion protection) - HIGH
- •Deprecated syntax (old interpolation, list(), map(), count vs for_each) - HIGH
- •Module structure (README, required files, backend) - MEDIUM
- •Dependency issues (excessive depends_on, circular deps) - MEDIUM
- •Missing descriptions (variables, outputs) - LOW
- •Naming conventions (snake_case enforcement) - LOW
Running Checks
Full audit (all checks):
node .claude/skills/terraform-audit/scripts/run_all_checks.mjs
Generate report (all checks + markdown report):
node .claude/skills/terraform-audit/scripts/generate_report.mjs
Report saved to: reports/YYYY-MM-DD/terraform-audit.md
Individual checks:
node .claude/skills/terraform-audit/scripts/check_hardcoded_secrets.mjs node .claude/skills/terraform-audit/scripts/check_security_issues.mjs node .claude/skills/terraform-audit/scripts/check_missing_versions.mjs node .claude/skills/terraform-audit/scripts/check_resource_lifecycle.mjs node .claude/skills/terraform-audit/scripts/check_deprecated_syntax.mjs node .claude/skills/terraform-audit/scripts/check_module_structure.mjs node .claude/skills/terraform-audit/scripts/check_dependency_issues.mjs node .claude/skills/terraform-audit/scripts/check_missing_descriptions.mjs node .claude/skills/terraform-audit/scripts/check_naming_conventions.mjs
Quality Rules
1. Hardcoded Secrets (HIGH)
RULE: Never hardcode sensitive values. Exposed secrets = compromised infrastructure.
Violations:
- •
password = "mysecretpassword" - •
api_key = "sk-1234567890" - •
access_key = "AKIA..." - •
github_token = "ghp_..." - •Any
_pat,_token,_secret,_keywith literal value
Fix: Use var.password, random_password.db.result, or secrets manager.
2. Security Issues (HIGH)
RULE: Follow least-privilege principle. Over-permissive = security breach waiting to happen.
Violations:
- •
"Action": "*"or"Resource": "*"in IAM policies - •
verbs = ["*"],resources = ["*"],api_groups = ["*"]in K8s RBAC - •
cidr_blocks = ["0.0.0.0/0"]- open to internet - •
encrypted = false- unencrypted data at rest - •
publicly_accessible = true- database exposed - •
privileged = true- container running as root - •
skip_final_snapshot = true- data loss on delete - •
deletion_protection = false- accidental deletion risk
Fix: Use specific permissions, restrict CIDR blocks, enable encryption, protect resources.
3. Missing Version Constraints (HIGH)
RULE: Pin versions for reproducibility. Unpinned = CI/CD failures + breaking changes in production.
Violations:
- •Provider without version in
required_providers - •Module from registry without
version - •GitHub/Git module without
?ref=or?tag= - •Missing
required_versionfor Terraform itself
Fix: Add version = "~> 2.0" to providers and modules.
4. Resource Lifecycle (HIGH)
RULE: Protect critical resources. No protection = data loss + downtime.
Violations:
- •Database/storage without
lifecycle { prevent_destroy = true } - •Helm release without
timeout(infinite hang possible) - •RDS/database without
deletion_protection = true - •RDS with
skip_final_snapshot = true - •EKS/GKE cluster without lifecycle protection
Fix: Add lifecycle blocks and deletion protection to critical resources.
5. Deprecated Syntax (HIGH)
RULE: Use modern Terraform syntax. Deprecated syntax = upgrade blockers + state corruption risk.
Violations:
- •
"${var.name}"instead ofvar.name(unnecessary interpolation) - •
list("a", "b")instead of["a", "b"](deprecated function) - •
map("key", "value")instead of{ key = "value" }(deprecated function) - •
count = length(var.x)instead offor_each(index-based state = corruption risk) - •
element(list, count.index)instead oflist[count.index] - •
terraform.workspaceusage (anti-pattern)
Fix: Update to modern HCL syntax before Terraform upgrades.
6. Module Structure (MEDIUM)
RULE: Follow standard module structure for maintainability.
Required files:
- •
variables.tf,outputs.tf,versions.tf,README.md
Violations:
- •Missing required files
- •Root module without backend configuration
- •Too many .tf files (>10) - split into modules
Fix: Add missing files, configure backend, refactor large modules.
7. Dependency Issues (MEDIUM)
RULE: Use implicit dependencies. Explicit depends_on = maintenance nightmare.
Violations:
- •
5
depends_onin one file (over-reliance) - •
depends_onwith data sources (usually unnecessary) - •
null_resourceprovisioner withoutdepends_onortriggers
Fix: Use resource references for implicit dependencies.
8. Missing Descriptions (LOW)
RULE: Document all variables and outputs for usability.
Violations:
- •
variable "name" { type = string }(no description) - •
output "id" { value = ... }(no description)
Fix: Add description = "..." to all variables and outputs.
9. Naming Conventions (LOW)
RULE: Use snake_case everywhere for consistency.
Violations:
- •camelCase:
myResourceName - •kebab-case:
my-resource-name
Fix: Rename to my_resource_name.
Safety
- •Read-only operation (except report generation)
- •No Terraform state modifications
- •No infrastructure changes