| name | terraform-audit |
| description | Audits Terraform code for anti-patterns, security issues, and best practice violations. Use when asked to audit, review, or check terraform code quality. Generates a comprehensive report under reports/YYYY-MM-DD/terraform-audit.md. (project) |
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 policiesverbs = ["*"],resources = ["*"],api_groups = ["*"]in K8s RBACcidr_blocks = ["0.0.0.0/0"]- open to internetencrypted = false- unencrypted data at restpublicly_accessible = true- database exposedprivileged = true- container running as rootskip_final_snapshot = true- data loss on deletedeletion_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