mirror of
https://github.com/github/awesome-copilot.git
synced 2026-02-20 18:35:14 +00:00
Add a new skill that analyzes Terraform plan JSON output for AzureRM Provider to distinguish between false-positive diffs (order-only changes in Set-type attributes) and actual resource changes. This skill helps users identify 'noise' in terraform plan output caused by Azure API returning Set elements in different order, making plan reviews easier and reducing confusion in CI/CD pipelines. Bundled assets: - references/azurerm_set_attributes.json - references/azurerm_set_attributes.md - scripts/analyze_plan.py
206 lines
5.2 KiB
Markdown
206 lines
5.2 KiB
Markdown
# Terraform AzureRM Set Diff Analyzer Script
|
|
|
|
A Python script that analyzes Terraform plan JSON and identifies "false-positive diffs" in AzureRM Set-type attributes.
|
|
|
|
## Overview
|
|
|
|
AzureRM Provider's Set-type attributes (such as `backend_address_pool`, `security_rule`, etc.) don't guarantee order, so when adding or removing elements, all elements appear as "changed". This script distinguishes such "false-positive diffs" from actual changes.
|
|
|
|
### Use Cases
|
|
|
|
- As an **Agent Skill** (recommended)
|
|
- As a **CLI tool** for manual execution
|
|
- For automated analysis in **CI/CD pipelines**
|
|
|
|
## Prerequisites
|
|
|
|
- Python 3.8 or higher
|
|
- No additional packages required (uses only standard library)
|
|
|
|
## Usage
|
|
|
|
### Basic Usage
|
|
|
|
```bash
|
|
# Read from file
|
|
python analyze_plan.py plan.json
|
|
|
|
# Read from stdin
|
|
terraform show -json plan.tfplan | python analyze_plan.py
|
|
```
|
|
|
|
### Options
|
|
|
|
| Option | Short | Description | Default |
|
|
|--------|-------|-------------|---------|
|
|
| `--format` | `-f` | Output format (markdown/json/summary) | markdown |
|
|
| `--exit-code` | `-e` | Return exit code based on changes | false |
|
|
| `--quiet` | `-q` | Suppress warnings | false |
|
|
| `--verbose` | `-v` | Show detailed warnings | false |
|
|
| `--ignore-case` | - | Compare values case-insensitively | false |
|
|
| `--attributes` | - | Path to custom attribute definition file | (built-in) |
|
|
| `--include` | - | Filter resources to analyze (can specify multiple) | (all) |
|
|
| `--exclude` | - | Filter resources to exclude (can specify multiple) | (none) |
|
|
|
|
### Exit Codes (with `--exit-code`)
|
|
|
|
| Code | Meaning |
|
|
|------|---------|
|
|
| 0 | No changes, or order-only changes |
|
|
| 1 | Actual Set attribute changes |
|
|
| 2 | Resource replacement (delete + create) |
|
|
| 3 | Error |
|
|
|
|
## Output Formats
|
|
|
|
### Markdown (default)
|
|
|
|
Human-readable format for PR comments and reports.
|
|
|
|
```bash
|
|
python analyze_plan.py plan.json --format markdown
|
|
```
|
|
|
|
### JSON
|
|
|
|
Structured data for programmatic processing.
|
|
|
|
```bash
|
|
python analyze_plan.py plan.json --format json
|
|
```
|
|
|
|
Example output:
|
|
```json
|
|
{
|
|
"summary": {
|
|
"order_only_count": 3,
|
|
"actual_set_changes_count": 1,
|
|
"replace_count": 0
|
|
},
|
|
"has_real_changes": true,
|
|
"resources": [...],
|
|
"warnings": []
|
|
}
|
|
```
|
|
|
|
### Summary
|
|
|
|
One-line summary for CI/CD logs.
|
|
|
|
```bash
|
|
python analyze_plan.py plan.json --format summary
|
|
```
|
|
|
|
Example output:
|
|
```
|
|
🟢 3 order-only | 🟡 1 set changes
|
|
```
|
|
|
|
## CI/CD Pipeline Usage
|
|
|
|
### GitHub Actions
|
|
|
|
```yaml
|
|
name: Terraform Plan Analysis
|
|
|
|
on:
|
|
pull_request:
|
|
paths:
|
|
- '**.tf'
|
|
|
|
jobs:
|
|
analyze:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Setup Terraform
|
|
uses: hashicorp/setup-terraform@v3
|
|
|
|
- name: Terraform Init & Plan
|
|
run: |
|
|
terraform init
|
|
terraform plan -out=plan.tfplan
|
|
terraform show -json plan.tfplan > plan.json
|
|
|
|
- name: Analyze Set Diff
|
|
run: |
|
|
python path/to/analyze_plan.py plan.json --format markdown > analysis.md
|
|
|
|
- name: Comment PR
|
|
uses: marocchino/sticky-pull-request-comment@v2
|
|
with:
|
|
path: analysis.md
|
|
```
|
|
|
|
### GitHub Actions (Gate with Exit Code)
|
|
|
|
```yaml
|
|
- name: Analyze and Gate
|
|
run: |
|
|
python path/to/analyze_plan.py plan.json --exit-code --format summary
|
|
# Fail on exit code 2 (resource replacement)
|
|
continue-on-error: false
|
|
```
|
|
|
|
### Azure Pipelines
|
|
|
|
```yaml
|
|
- task: TerraformCLI@0
|
|
inputs:
|
|
command: 'plan'
|
|
commandOptions: '-out=plan.tfplan'
|
|
|
|
- script: |
|
|
terraform show -json plan.tfplan > plan.json
|
|
python scripts/analyze_plan.py plan.json --format markdown > $(Build.ArtifactStagingDirectory)/analysis.md
|
|
displayName: 'Analyze Plan'
|
|
|
|
- task: PublishBuildArtifacts@1
|
|
inputs:
|
|
pathToPublish: '$(Build.ArtifactStagingDirectory)/analysis.md'
|
|
artifactName: 'plan-analysis'
|
|
```
|
|
|
|
### Filtering Examples
|
|
|
|
Analyze only specific resources:
|
|
```bash
|
|
python analyze_plan.py plan.json --include application_gateway --include load_balancer
|
|
```
|
|
|
|
Exclude specific resources:
|
|
```bash
|
|
python analyze_plan.py plan.json --exclude virtual_network
|
|
```
|
|
|
|
## Interpreting Results
|
|
|
|
| Category | Meaning | Recommended Action |
|
|
|----------|---------|-------------------|
|
|
| 🟢 Order-only | False-positive diff, no actual change | Safe to ignore |
|
|
| 🟡 Actual change | Set element added/removed/modified | Review the content, usually in-place update |
|
|
| 🔴 Resource replacement | delete + create | Check for downtime impact |
|
|
|
|
## Custom Attribute Definitions
|
|
|
|
By default, uses `references/azurerm_set_attributes.json`, but you can specify a custom definition file:
|
|
|
|
```bash
|
|
python analyze_plan.py plan.json --attributes /path/to/custom_attributes.json
|
|
```
|
|
|
|
See `references/azurerm_set_attributes.md` for the definition file format.
|
|
|
|
## Limitations
|
|
|
|
- Only AzureRM resources (`azurerm_*`) are supported
|
|
- Some resources/attributes may not be supported
|
|
- Comparisons may be incomplete for attributes containing `after_unknown` (values determined after apply)
|
|
- Comparisons may be incomplete for sensitive attributes (they are masked)
|
|
|
|
## Related Documentation
|
|
|
|
- [SKILL.md](../SKILL.md) - Usage as an Agent Skill
|
|
- [azurerm_set_attributes.md](../references/azurerm_set_attributes.md) - Attribute definition reference
|