一键导入
review-drift
[pr-review-focus-area: IaC Drift] Detect drift between IaC state (Terraform/Pulumi/CloudFormation) and live cloud or baremetal reality.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
[pr-review-focus-area: IaC Drift] Detect drift between IaC state (Terraform/Pulumi/CloudFormation) and live cloud or baremetal reality.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Research a work item, draft an implementation plan, and begin work after approval.
Guided one-shot install — discover installed plugins (or help install new ones), pick install scope, calibrate risk tolerance into a concrete allowlist + hooks, scaffold or merge CLAUDE.md, and sanity-check the result.
Finalize work — commit via /commit, push, and create PRs on feature branches.
Reviewer-side PR workflow — checks out the branch in a worktree, runs focus-area reviews plus a senior-engineering pass, optionally cross-checks against an autonomous reviewer, and posts inline findings only on explicit approval. Read-only — never edits, commits, or pushes.
Fetch PR review comments, classify by severity and confidence, and fix the selected subset.
Triage CVE and SBOM scanner output (Trivy, Grype, Snyk, Docker Scout, Dependabot) into a ranked, deduplicated action list.
| name | review-drift |
| description | [pr-review-focus-area: IaC Drift] Detect drift between IaC state (Terraform/Pulumi/CloudFormation) and live cloud or baremetal reality. |
| user-invocable | true |
| disable-model-invocation | true |
| allowed-tools | ["Read","Bash","Grep","Glob"] |
| argument-hint | [module path] |
Compare declared infrastructure-as-code state against live cloud or baremetal reality, classify each drifted resource, and surface likely owners. This skill is read-only — it never runs apply, destroy, upgrade, or any mutating command.
The user runs /review-drift [module path]. When no argument is supplied, scan from the repo root and auto-detect IaC modules. When a path is supplied, scope detection and planning to that directory and its descendants.
Run the steps in order. For each step, report PASS, FAIL, SKIPPED (tool or credential missing), or N/A (no matching files).
Run the shared scope helper. Prefer ${CLAUDE_PLUGIN_ROOT}/scripts/detect-iac-scope.sh and fall back to plugins/infra/scripts/detect-iac-scope.sh when running from the plugin dev repo.
SCRIPT="${CLAUDE_PLUGIN_ROOT:-plugins/infra}/scripts/detect-iac-scope.sh"
[ -x "$SCRIPT" ] || SCRIPT="plugins/infra/scripts/detect-iac-scope.sh"
"$SCRIPT" "${1:-.}"
Parse the JSON output. Process the modules each tool reports independently and aggregate results:
| Tool | JSON field |
|---|---|
| Terraform | .terraform.present + .terraform.modules[] |
| Pulumi | .pulumi.present + .pulumi.stacks[] |
| CloudFormation | .cloudformation.present + .cloudformation.templates[] |
If none of the three are present: true, report SKIPPED with the reason "no IaC artifacts detected" and exit with verdict INCONCLUSIVE.
For each detected tool, run the non-mutating diff command:
terraform plan -detailed-exitcode -no-color -lock=false in each module directory that has .terraform/ present. Exit code 0 = no changes, 2 = drift present, 1 = error. If the module is not initialized, mark SKIPPED for that module — do NOT run terraform init.pulumi preview --diff --non-interactive from the stack directory. A non-empty resource diff = drift present.aws cloudformation detect-stack-drift --stack-name <name> followed by describe-stack-resource-drifts. Any status other than IN_SYNC = drift present.If credentials are missing, a state lock is held, or the provider is unauthenticated, mark the module INCONCLUSIVE and continue. Do not attempt to acquire credentials or break locks.
For every drifted resource returned by step 2, assign exactly one tag:
# forgets, CFN NOT_CHECKED with live match, Pulumi read diff).~, Pulumi update, CFN MODIFIED).-, Pulumi delete, CFN DELETED).When a classification is ambiguous (e.g. partial read), mark it unclear and include the raw plan fragment in the report appendix rather than guessing.
For each non-noise drifted resource:
owner, team, managed_by, cost-center, or service. Surface the first match.CODEOWNERS (root, .github/, or docs/) for the IaC file that declared the resource. If a CODEOWNERS entry matches, list its owners alongside the tag owner.unknown — do NOT infer an owner from author history or guesswork.Group findings by owner/team first, then by severity (deleted > modified > added > provider-side). Render the report shape below.
## Drift Report - <module>
| Resource | Type | Drift | Likely cause | Owner |
|----------|------|-------|--------------|-------|
| aws_security_group.web | modified | ingress rule added | click-ops | platform |
| aws_s3_bucket.logs | added-outside-IaC | bucket exists live, not in state | manual console | unknown |
| google_compute_disk.cache | deleted-outside-IaC | disk removed live, still in state | cleanup script | sre |
**Totals:** added: N, modified: N, deleted: N, provider-noise: N
**Verdict:** <CLEAN | DRIFT-PRESENT | INCONCLUSIVE>
Include a ### Appendix: unclear classifications section only when step 3 produced unclear rows, and paste the verbatim plan fragment for each.
0, Pulumi preview is empty, or CloudFormation returns IN_SYNC; alternatively, only provider-side entries remain after classification.added-outside-IaC, modified-outside-IaC, or deleted-outside-IaC rows exist.terraform apply, terraform init, terraform refresh, pulumi up, pulumi refresh, aws cloudformation update-stack, or any mutating operation.terraform, pulumi, aws) is not installed, or credentials are missing, mark the affected module SKIPPED and continue.unclear and quote the raw plan fragment.-lock=false when a lock is legitimately held, do not write to remote state backends.$ARGUMENTS