agentleFS
rhawk117rhawk117/cc-terraform-harness/skills/review-module/SKILL.md

review-module

Skill1 starsChanged 26 days agoApache-2.0View on GitHub

Review and grade Terraform (HCL) code, a whole repository or a feature branch, as the engineer who has to run the apply: what would terraform plan print, and can the code predict it. Reads the code against an eight-category rubric, and writes APPLY-CALYPSE-REPORT.md with a letter grade, a BLOCK / APPLY WITH CONDITIONS / CLEAR verdict, a plan forecast, and file:line findings with fix and verify steps. Use whenever the user wants Terraform, .tf files, HCL, IaC, modules, state layout, or a Terraform PR reviewed, graded, audited, or checked for merge or apply safety: "review my terraform", "is this safe to apply", "grade this IaC", "will this plan destroy anything", "run review-module", or any quality question about a mostly-.tf repo.

  • Reads credentials

The file

Show its rules and text

We split this skill into the rules it gives an agent

17 rules. About 0 are common, 6 are distinctive, and 11 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈6

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 11

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    When the request is ambiguous ("look at this terraform" inside a repo on a feature branch), ask which mode before starting.

    line 44
  2. Very specific:

    Call describe on the repository root, or on each candidate directory.

    line 59
  3. Very specific:

    Read two parts of the diff before the rest: every change to .terraform.lock.hcl, required_providers, required_version, or a module source …

    line 97
  4. Distinctive:

    Read references/rubric.md in full before judging.

    line 119
  5. Distinctive:

    Read code in this order:

    line 123
  6. Very specific:

    Every terraform block and backend config: where is state, is it locked, what is pinned.

    line 125
  7. Very specific:

    Every moved, removed, and import block.

    line 127
  8. Distinctive:

    Every stateful resource (databases, buckets, disks, keys, secrets): protection, indexing mode, immutable arguments touched, including …

    line 128
  9. Distinctive:

    Every IAM policy and every network rule: wildcards and service-wide actions (SE6), missing hardening and open CIDRs (SE7).

    line 131
  10. Very specific:

    Every variable and output of every module a root calls: the contract.

    line 133
  11. Very specific:

    Before writing findings, write the forecast.

    line 145
  12. Very specific:

    If the user hands you a plan rendered with terraform show -json, call plan_digest on it and reconcile your forecast against …

    line 152
  13. Very specific:

    If terraform is installed and the user permits, terraform init -backend=false && terraform validate in each root is cheap and catches …

    line 159
  14. Very specific:

    Run diagnostics on each reviewed module and record its fmt, validate, and tflint checks.

    line 164
  15. Distinctive:

    Follow references/report.md exactly: severity ladder, category grades, weighted overall grade with its caps, deterministic verdict, one …

    line 175
  16. Very specific:

    Delete anything that fails.

    line 187
  17. Very specific:

    Do not run terraform plan or apply without explicit permission, and never apply at all.

    line 204

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

review-module

You are the engineer who has to run the apply. You do not care whether the HCL is elegant; you care whether you can read the code and predict, line by line, what terraform plan will print, and whether anything in that plan destroys data, leaks a secret, or drifts between machines. Good Terraform makes the plan boring. Your job is to find every place where it would not be.

Findings feed engineers and agents who will fix them, so each one must be actionable without re-deriving your analysis: rule ID, file:line, the plan line it would cause, the fix, and how to verify the fix.

Modes

Repository (default when no branch, PR, or diff is named): grade the whole tree as it stands. The verdict answers "would I let this repository's pipeline apply to production today".

Branch (when the user names a branch, PR, diff, or asks about merging or applying a change): review what the branch changes plus everything the change reaches. The verdict answers "would I let this branch's plan run". Branch mode adds the address-diff comparison and the plan forecast is mandatory and specific.

When the request is ambiguous ("look at this terraform" inside a repo on a feature branch), ask which mode before starting.

Workflow

1. Ground truth

Repository mode:

git rev-parse --show-toplevel
git ls-files '*.tf' | wc -l
git ls-files | grep -E '\.terraform\.lock\.hcl$'

Call describe on the repository root, or on each candidate directory; it returns kind (module, file or tfvars), variables, outputs, resources, data_sources, required_providers, and module_calls with their refs. It does not say whether a directory is a root or a child module, or where state lives: read the terraform blocks and provider configuration yourself to tell them apart and to find the backend. Note where state lives and whether the backend config is in the repo at all; a partial backend whose keys are supplied elsewhere goes in Not verified and caps the verdict. Check the backend key, workspace, account, and region against what the request targets before reading further (BR11).

For a module directory or a .tf file, describe returns path, kind, variables, outputs, resources, data_sources, module_calls, required_providers and problems; for a .tf file that is a summary of that file's blocks only. Each entry carries its file and line range. For a .tfvars file it returns path, kind, declared, undeclared and problems. To find a file's sibling consumers, describe the containing module directory, then read or search the sibling files for references.

For any question that crosses roots, dispatch terraform-researcher with the question rather than guessing; report what the repository does and does not establish.

Branch mode, additionally:

git merge-base <base> <branch>
git diff --stat <merge-base>...<branch> -- '*.tf' '*.tfvars' '*.hcl'
git log --oneline <merge-base>..<branch>
git diff <merge-base>...<branch>
git log -p <merge-base>..<branch> -- '*.tfvars' '*.env' '*.json' | grep -inE 'password|secret|token|key' | head

The base is whatever the user names, otherwise the repository default branch. Three dots so you review only the branch's own work. The last command is for SE5: a secret added and removed on the branch is still in history after merge.

Read two parts of the diff before the rest: every change to .terraform.lock.hcl, required_providers, required_version, or a module source or version (VE8), and every line that removes or weakens prevent_destroy, deletion_protection, skip_final_snapshot, or force_destroy (BR10). When the branch fixes an earlier finding or a scanner result, run the false-negative checklist in rubric section 10 and review the whole module, not only the rule that was targeted.

Size triage. Under roughly 40 .tf files: read everything. Larger: read every root, every module that a root calls, and a representative spread of the rest; list skimmed files in Not verified. Never silently sample.

Route the reading through terraform-researcher. It is cheap and disposable, so dispatch one per root and one per called module, in parallel, each with the question "what does this declare, what does it read, who depends on it, and what is unknown". Keep the reports; the reports are your read evidence for everything below Critical and High. Read the files yourself only where a report says unknown, where a finding will be Critical or High, and for the false-positive checklist.

2. Read the rubric, then the code

Read references/rubric.md in full before judging. It holds the eight categories, the rule IDs, and the false-positive checklist. Grade from it, not from memory.

Read code in this order:

  1. Every terraform block and backend config: where is state, is it locked, what is pinned.
  2. Every moved, removed, and import block. This is where destroys hide.
  3. Every stateful resource (databases, buckets, disks, keys, secrets): protection, indexing mode, immutable arguments touched, including through a variable default or tfvars value (RA5).
  4. Every IAM policy and every network rule: wildcards and service-wide actions (SE6), missing hardening and open CIDRs (SE7).
  5. Every variable and output of every module a root calls: the contract. describe on the module directory lists both.
  6. The remaining files for naming, hardcoding, literals and defaults that trace to nothing (IN9), conditional logic, and depends_on that a reference would replace.

While reading, keep a ledger: rule ID, file:line, evidence line, the plan line it would cause. Run each candidate through the false-positive checklist before it becomes a finding.

3. Plan forecast

Before writing findings, write the forecast. Branch mode: for each address the diff touches, state what plan prints (no changes, will be updated in-place, must be replaced, will be destroyed, will be created) and why. For each touched output or module source, inspect the repository's callers and state references; a consumer in another root belongs in the forecast. Repository mode: name the addresses whose next routine edit is most likely to destroy or replace something, and why.

If the user hands you a plan rendered with terraform show -json, call plan_digest on it and reconcile your forecast against resource_changes, moves, imports, and plan_flags before grading. Check every replacement's forced_by against the stateful types (RA5), every move's identifying attributes before and after (RA7), and the resolved IAM documents rather than the HCL that renders them (SE6).

If terraform is installed and the user permits, terraform init -backend=false && terraform validate in each root is cheap and catches syntax and type errors. Do not run terraform plan against a real backend unless the user explicitly asks; a plan can require credentials and can lock state. Never run apply.

Run diagnostics on each reviewed module and record its fmt, validate, and tflint checks. A validate failure is a finding under a [validate] rule: an unexpected argument or block, or an unsupported resource type, is VE7; an undeclared resource or module is DE5, and an undeclared variable IN8; a missing required argument is IN10; a duplicate provider configuration is ST7. diagnostics does not initialize Terraform. When an existing plan rendered as JSON is available, use plan_digest to read its actions, moves, imports, and risk flags.

5. Grade, verdict, write

Follow references/report.md exactly: severity ladder, category grades, weighted overall grade with its caps, deterministic verdict, one flavor line, and the template. Write APPLY-CALYPSE-REPORT.md at the repository root unless told otherwise.

6. Verify before delivering

For every Critical and High finding: reopen the file, confirm the line number and the quoted text, confirm no false-positive carve-out applies, and confirm the plan-impact line is what Terraform would actually print for that change. Recompute the overall grade from the category table by hand and check the caps. Confirm the verdict follows from the findings. Delete anything that fails. A wrong file:line in a report that grades other people's rigor is a self-inflicted F.

Honesty rules

  • Findings require read evidence. A terraform-researcher <fact> with a location is read evidence; Critical and High findings are reopened by you regardless of who read them first.
  • A clean repository gets an A, CLEAR, and a short report. Do not manufacture findings to look thorough. Over-abstraction (LO8) exists as a finding so both failure directions are covered.
  • Severity is about what apply does. If you cannot name the plan line or the exposure path, it is not Critical.
  • State scope limits plainly: files skimmed, backend config not in repo, or base unavailable.
  • Grade the code, not the authors. No sarcasm anywhere except the single epigraph line.
  • Do not run terraform plan or apply without explicit permission, and never apply at all.
  • Claims about provider or cloud behavior (which argument forces a replacement, what an attribute exposes, when user_data runs) come from the schema, the provider documentation, or the plan, and the finding says which. Memory is not a source.

Anti-patterns

  • Converting a file name or diff hunch straight into a finding without opening the file. The false-positive checklist exists to prevent that.
  • Reviewing only the diff in branch mode. A renamed output breaks the root that consumes it, and that root is not in the diff.
  • Grading style. Formatting is terraform fmt's job; if it is not enforced in CI, that is one Low finding under ST4, not twenty.
  • Rewarding DRY for its own sake. Three readable roots beat one unreadable module. See LO8.
  • Reporting only problems. Clean categories get their evidence line.
  • Taking idiomatic style as evidence. Generated Terraform is uniformly clean whether it is right or wrong; schema, plan, diff, and permissions decide. See rubric section 10.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.