Terraform AzureRM set diff analyzer
Generate Terraform plan JSON, run the bundled analyzer, and classify noisy AzureRM Set-type diffs as false positives or actual infrastructure changes from terraform plan.
When to invoke
- "This Terraform plan shows all Application Gateway blocks changed after one edit."
- "Analyze AzureRM set diffs in plan.json."
- "Filter false-positive Terraform diffs in CI."
- "Is this Load Balancer, Firewall, Front Door, or NSG plan change real?"
Prerequisites and context
- Python 3.8+ is required. If
python is unavailable, use python3, install with a package manager such as apt install python3 or brew install python3, or use https://www.python.org/downloads/.
- Terraform must be able to create a saved plan and render JSON in the target workspace.
- The analyzer uses only the Python standard library;
ModuleNotFoundError usually means the wrong interpreter is being invoked.
Procedure
- Generate a binary Terraform plan:
terraform plan -out=plan.tfplan.
- Convert it to JSON:
terraform show -json plan.tfplan > plan.json.
- Run the bundled analyzer:
python scripts/analyze_plan.py plan.json or python3 scripts/analyze_plan.py plan.json.
- Read the classification before approving, rejecting, or suppressing plan noise in CI/CD.
Diff classification
| Plan signal |
Likely classification |
Review action |
| One element added or removed and sibling Set elements appear reordered |
False-positive diff |
Confirm identity keys match and suppress only the order-only noise; this is the classic added/removed Set case. |
| Attribute values changed inside the same logical element |
Actual change |
Review as a real resource update. |
| Element identity key changed |
Actual change |
Treat as delete/create even if nested values look similar. |
| Many AzureRM nested blocks changed after one edit |
Suspect Set ordering |
Compare by stable keys rather than displayed position. |
| Unsupported resource or attribute |
Unknown |
Use references/azurerm_set_attributes.md or the provider schema before classifying. |
Terraform's Set type is unordered, but plan display can make internally reordered nested blocks look like position-by-position changes. AzureRM resources with nested collections such as Application Gateway, Load Balancer, Firewall, Front Door, and NSG expose this often.
Progressive disclosure and bundled resources
scripts/analyze_plan.py: deterministic analyzer for Terraform plan JSON.
scripts/README.md: full options, output formats, exit codes, and CI/CD examples.
references/azurerm_set_attributes.md: supported AzureRM resources and attributes.
references/azurerm_set_attributes.json: machine-readable Set attribute catalog.
Troubleshooting
| Symptom |
Likely cause |
Resolution |
python: command not found |
System exposes Python as python3. |
Run python3 scripts/analyze_plan.py plan.json or install Python 3.8+. |
ModuleNotFoundError |
Wrong interpreter or broken environment. |
Use Python 3.8+; the script needs only the standard library. |
| Analyzer reports unknown attributes |
Catalog does not cover that nested block. |
Inspect references/azurerm_set_attributes.md and manually compare stable keys. |
Output template
## Terraform AzureRM set diff analysis - <plan file>
**Status:** false-positive diffs found | actual changes found | mixed | blocked
**Command:** `python scripts/analyze_plan.py <plan.json>`
| Resource | Attribute path | Classification | Evidence | Action |
| --- | --- | --- | --- | --- |
| `<azurerm resource>` | `<nested Set path>` | `false positive` | `<same keys, reordered>` | `<safe to ignore in review>` |
| `<azurerm resource>` | `<attribute>` | `actual change` | `<value or identity changed>` | `<review/apply decision>` |
### Validation
- `terraform plan -out=plan.tfplan`: <pass/fail/not run>
- `terraform show -json plan.tfplan > plan.json`: <pass/fail/not run>
- Analyzer exit code: <code>
Quality gate
References
1---2name: terraform-azurerm-set-diff-analyzer3description: Analyze Terraform plan JSON for AzureRM Provider Set-type attribute noise and separate order-only false-positive diffs from real Azure resource changes. Use when Application Gateway, Load Balancer, Firewall, Front Door, NSG, or other Azure resources show many changed elements after one add, remove, or reorder.4license: MIT5---67<!-- Generated from harness/github-copilot/skills/terraform-azurerm-set-diff-analyzer/SKILL.md by harness/claude-code/scripts/convert_from_copilot.py. Edit the source, not this file. -->89# Terraform AzureRM set diff analyzer1011Generate Terraform plan JSON, run the bundled analyzer, and classify noisy AzureRM Set-type diffs as false positives or actual infrastructure changes from `terraform plan`.1213## When to invoke1415- "This Terraform plan shows all Application Gateway blocks changed after one edit."16- "Analyze AzureRM set diffs in plan.json."17- "Filter false-positive Terraform diffs in CI."18- "Is this Load Balancer, Firewall, Front Door, or NSG plan change real?"1920## Prerequisites and context2122- Python 3.8+ is required. If `python` is unavailable, use `python3`, install with a package manager such as `apt install python3` or `brew install python3`, or use https://www.python.org/downloads/.23- Terraform must be able to create a saved plan and render JSON in the target workspace.24- The analyzer uses only the Python standard library; `ModuleNotFoundError` usually means the wrong interpreter is being invoked.2526## Procedure27281. Generate a binary Terraform plan: `terraform plan -out=plan.tfplan`.292. Convert it to JSON: `terraform show -json plan.tfplan > plan.json`.303. Run the bundled analyzer: `python scripts/analyze_plan.py plan.json` or `python3 scripts/analyze_plan.py plan.json`.314. Read the classification before approving, rejecting, or suppressing plan noise in CI/CD.3233## Diff classification3435| Plan signal | Likely classification | Review action |36| --- | --- | --- |37| One element added or removed and sibling Set elements appear reordered | False-positive diff | Confirm identity keys match and suppress only the order-only noise; this is the classic added/removed Set case. |38| Attribute values changed inside the same logical element | Actual change | Review as a real resource update. |39| Element identity key changed | Actual change | Treat as delete/create even if nested values look similar. |40| Many AzureRM nested blocks changed after one edit | Suspect Set ordering | Compare by stable keys rather than displayed position. |41| Unsupported resource or attribute | Unknown | Use `references/azurerm_set_attributes.md` or the provider schema before classifying. |4243Terraform's `Set` type is unordered, but plan display can make internally reordered nested blocks look like position-by-position changes. AzureRM resources with nested collections such as Application Gateway, Load Balancer, Firewall, Front Door, and NSG expose this often.4445## Progressive disclosure and bundled resources4647- `scripts/analyze_plan.py`: deterministic analyzer for Terraform plan JSON.48- `scripts/README.md`: full options, output formats, exit codes, and CI/CD examples.49- `references/azurerm_set_attributes.md`: supported AzureRM resources and attributes.50- `references/azurerm_set_attributes.json`: machine-readable Set attribute catalog.5152## Troubleshooting5354| Symptom | Likely cause | Resolution |55| --- | --- | --- |56| `python: command not found` | System exposes Python as `python3`. | Run `python3 scripts/analyze_plan.py plan.json` or install Python 3.8+. |57| `ModuleNotFoundError` | Wrong interpreter or broken environment. | Use Python 3.8+; the script needs only the standard library. |58| Analyzer reports unknown attributes | Catalog does not cover that nested block. | Inspect `references/azurerm_set_attributes.md` and manually compare stable keys. |5960## Output template6162```markdown63## Terraform AzureRM set diff analysis - <plan file>6465**Status:** false-positive diffs found | actual changes found | mixed | blocked66**Command:** `python scripts/analyze_plan.py <plan.json>`6768| Resource | Attribute path | Classification | Evidence | Action |69| --- | --- | --- | --- | --- |70| `<azurerm resource>` | `<nested Set path>` | `false positive` | `<same keys, reordered>` | `<safe to ignore in review>` |71| `<azurerm resource>` | `<attribute>` | `actual change` | `<value or identity changed>` | `<review/apply decision>` |7273### Validation74- `terraform plan -out=plan.tfplan`: <pass/fail/not run>75- `terraform show -json plan.tfplan > plan.json`: <pass/fail/not run>76- Analyzer exit code: <code>77```7879## Quality gate8081- [ ] Plan JSON came from `terraform show -json plan.tfplan`, not from human plan text.82- [ ] Every false-positive claim is backed by stable identity-key comparison, not visual similarity.83- [ ] Actual value changes, identity changes, additions, and removals remain visible in the output.84- [ ] Unsupported attributes are labeled unknown instead of suppressed.85- [ ] `scripts/README.md` was used for CI/CD options or exit-code behavior when automation is requested.8687## References8889- [Python downloads](https://www.python.org/downloads/)