terraform-azurerm-set-diff-analyzer

Verified·Scanned 2/18/2026

Analyzes Terraform plan JSON for AzureRM Set-type attribute false-positive diffs. The documentation and examples instruct executing local shell commands such as terraform plan and python scripts/analyze_plan.py, which run CLI tools on the host.

by github·v8480453·47.2 KB·69 installs
Scanned from main at 8480453 · Transparency log ↗
$ vett add github/awesome-copilot/terraform-azurerm-set-diff-analyzer

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

# Read from file
python analyze_plan.py plan.json

# Read from stdin
terraform show -json plan.tfplan | python analyze_plan.py

Options

OptionShortDescriptionDefault
--format-fOutput format (markdown/json/summary)markdown
--exit-code-eReturn exit code based on changesfalse
--quiet-qSuppress warningsfalse
--verbose-vShow detailed warningsfalse
--ignore-case-Compare values case-insensitivelyfalse
--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)

CodeMeaning
0No changes, or order-only changes
1Actual Set attribute changes
2Resource replacement (delete + create)
3Error

Output Formats

Markdown (default)

Human-readable format for PR comments and reports.

python analyze_plan.py plan.json --format markdown

JSON

Structured data for programmatic processing.

python analyze_plan.py plan.json --format json

Example output:

{
  "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.

python analyze_plan.py plan.json --format summary

Example output:

🟢 3 order-only | 🟡 1 set changes

CI/CD Pipeline Usage

GitHub Actions

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)

      - 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

- 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:

python analyze_plan.py plan.json --include application_gateway --include load_balancer

Exclude specific resources:

python analyze_plan.py plan.json --exclude virtual_network

Interpreting Results

CategoryMeaningRecommended Action
🟢 Order-onlyFalse-positive diff, no actual changeSafe to ignore
🟡 Actual changeSet element added/removed/modifiedReview the content, usually in-place update
🔴 Resource replacementdelete + createCheck for downtime impact

Custom Attribute Definitions

By default, uses references/azurerm_set_attributes.json, but you can specify a custom definition file:

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 - Usage as an Agent Skill
  • azurerm_set_attributes.md - Attribute definition reference