🛠
skills.md
Back to Skills Catalog
Terraformv0.1.0License: MIT
View on GitHub

terraform-review

Reviews Terraform and other HashiCorp configuration for correctness, security, state risk, drift, and cost. Use when examining .tf files, modules, terraform plan output, pull requests that change infrastructure as code, or suspected state lock and drift problems.

Installnpx skills add Shaikdavudh11/skills.md --skill terraform-review
Compatibility: Terraform CLI is optional. Static review works from files and pasted plan output. Never apply without explicit approval.

Terraform review

Review infrastructure as code. Prefer static analysis and terraform plan. Never apply, destroy, or force-unlock state unless the user explicitly authorizes the exact command.

Purpose and scope

In scope

  • Terraform *.tf, *.tfvars (redacted), modules, and version constraints
  • terraform plan / terraform show output the user provides
  • Security issues: public exposure, IAM wildcards, unencrypted storage, missing logging
  • State backend, locking, workspace, and drift process (how to detect, not silent repair)
  • Cost smells: oversized instances, unused NAT, untagged resources, overly broad replication

Out of scope

  • Authoring a full greenfield AWS account architecture (hand off to an AWS review Skill)
  • Kubernetes workload crashes (use kubernetes-troubleshooting)
  • Running terraform apply or terraform destroy as part of the review
  • Inventing plan output, state serials, or remote backend contents

When to use

Use this Skill when the user asks for a Terraform code review, IaC security review, plan interpretation, drift explanation, state lock help, or cost reduction on Terraform-managed resources.

Do not use it to debug GitHub Actions YAML or to run an incident command structure.

Inputs

  • Root module path (default: current directory)
  • Cloud provider(s) in use
  • Whether this is a PR review, a local plan, or a production change
  • Plan file (tfplan or terraform show -json) when available
  • Backend type (S3/GCS/azurerm/remote/local) if known

If there are no .tf files and no plan output, stop and ask. Do not invent a module tree.

Workflow

- [ ] 1. Inventory modules and providers
- [ ] 2. Run read-only scans
- [ ] 3. Review security and IAM
- [ ] 4. Review state, locking, and blast radius
- [ ] 5. Interpret plan if present
- [ ] 6. Cost and operability
- [ ] 7. Report findings with severity
- [ ] 8. Stop before apply

1. Inventory

find . -name '*.tf' -not -path '*/.terraform/*' | sort
terraform version
terraform fmt -check -recursive

Read required_version, required_providers, backend block, and the graph of module sources. Pin versions; flag latest and unpinned git modules.

2. Read-only scans

If the helper is available:

python3 scripts/scan-terraform.py .

The scanner is heuristic. Treat hits as leads, not proof. Also run, when Terraform is installed and the user wants a plan without apply:

terraform init -backend=false
terraform validate
terraform plan -no-color -input=false

Use -backend=false only when you cannot reach the backend and the user agrees that providers/modules may still need network. Prefer a normal init (no apply) when credentials for read exist.

Do not pass -auto-approve. Do not run terraform apply. Do not run terraform destroy. Do not run terraform force-unlock without explicit approval.

3. Security and IAM

Walk references/review-checklist.md. High-severity patterns:

  • 0.0.0.0/0 on SSH (22), RDP (3389), or databases
  • S3/GCS buckets with public ACL or ignore_public_acls disabled plus public policy
  • Missing encryption (encrypted = false, no KMS)
  • IAM Action = "*" with Resource = "*"
  • Security groups referenced but never attached
  • Secrets in .tf or committed .tfvars (password, secret_key, private keys)

Redact secret values in the report. Point to the file and resource address only.

4. State, locking, and blast radius

  • Local state (terraform.tfstate in git) is a critical finding.
  • Remote backends need locking (S3 + DynamoDB / native lock, GCS, azurerm).
  • -target in history or docs is a smell; call out partial apply risk.
  • terraform state rm / mv are mutating; describe the procedure, do not execute.
  • Drift: plan showing unexpected in-place or destroy/create. Ask what changed out of band. Do not refresh-only against prod without approval (terraform apply -refresh-only is still an apply).

5. Interpret the plan

Classify each change:

Plan verbReview focus
+ createCost, exposure, naming, tags, dependencies
~ update in-placeDowntime, IAM widening, public access flips
- destroyData loss, state orphans, DNS
-/+ replaceReplacement triggers (force_new), disks, IPs

Count resources. A 200-resource replace in prod is an incident-in-waiting; recommend split or targeted (still gated) rollout.

If there is no plan, say plan not provided and limit claims to static code.

6. Cost

Flag: t2/t3.2xlarge without justification, untagged resources, NAT Gateway per AZ without need, aws_eip unattached, RDS Multi-AZ on a sandbox, verbose CloudWatch logs with no retention, unused load balancers in code that always create them.

Do not quote a dollar figure unless the user supplied pricing data.

7. Report

Use the output template. Sort by severity. Every finding needs file path + resource address + why + fix.

8. Approval gate

Never terraform apply without explicit user authorization of the exact command line, workspace, and target environment.

Best practices

  • Prefer terraform plan -out=tfplan then a reviewed apply tfplan (user-run).
  • prevent_destroy on state buckets, databases, and KMS keys.
  • Restrict provider aliases; accidental alias mix-ups create resources in the wrong account.
  • Use terraform fmt and validate in CI; this Skill does not replace CI.
  • Modules from the public registry need pinned versions, not version = ">= 0".
  • for_each over counted resources when identities matter (IAM, security groups).
  • Separate plan permissions from apply permissions in CI roles.
  • Do not store production state in developer laptops.

Commands and examples

Static review only

python3 scripts/scan-terraform.py infra/live/prod

Example scanner finding (illustration):

HIGH examples/insecure-s3.tf:12 aws_s3_bucket.logs acl = "public-read"
HIGH examples/iam.tf:8 aws_iam_policy.too_open Action="*" Resource="*"

Plan review (example excerpt)

Plan: 1 to add, 1 to change, 0 to destroy.

~ aws_security_group.api
    ingress.cidr_blocks: ["10.0.0.0/8"] => ["0.0.0.0/0"]

This is a high-severity exposure change. Do not apply.

State lock (example)

User sees Error acquiring the state lock. Collect lock ID and who holds it. Recommend waiting or contacting the holder. terraform force-unlock <ID> is last resort and approval-gated; unlocking under a live apply corrupts state.

Expected output

# Terraform review

## Scope
- Paths / modules:
- Terraform version:
- Backend:
- Plan provided: yes/no
- Environment assumption:

## Summary
- Blockers:
- High:
- Medium:
- Low:

## Findings
### [SEVERITY] short title
- Address / file:
- Evidence:
- Impact:
- Recommended change:
- Requires apply: yes/no

## Plan interpretation
- Creates / updates / destroys / replaces:
- Data-loss risks:
- Exposure changes:

## Cost notes
- Qualitative only unless prices were provided.

## Approval required
Exact mutating commands that remain blocked.

## Assumptions and limitations
What was not executed (no apply, maybe no init).

Error handling

SituationAction
No Terraform CLIStatic review + scanner only; say validate/plan were skipped
init needs credentialsDo not paste access keys; ask the user to init locally and provide plan
Backend access deniedReview code; do not disable the backend to fake a plan
Parse error in .tfQuote the HCL error; do not "fix and apply"
Mixed TerragruntReview generated/used Terraform; do not run terragrunt apply
Scanner false positiveKeep the finding as informational if unsure; do not hide it

Never create fake terraform plan results to fill the report.

Security and safety

  • Redact AWS_SECRET_ACCESS_KEY, tokens, private keys, and tfvars secret values.
  • Do not commit or echo .terraform/ or terraform.tfstate.
  • Do not terraform apply, destroy, refresh-only apply, or force-unlock without explicit authorization.
  • Do not broaden IAM (*) or open 0.0.0.0/0 as a "temporary" debug step.
  • Do not switch terraform workspace on a shared backend without confirmation (wrong workspace apply is a classic outage).
  • Treat local-exec provisioners as arbitrary code execution; flag them.

Additional resources