Thanks to visit codestin.com
Credit goes to github.com

Skip to content

mwhooo/AzureDriftDetector

Repository files navigation

Azure Configuration Drift Detector

A sophisticated C# console application that detects configuration drift between Bicep/ARM templates and live Azure resources. Built for DevOps teams practicing Infrastructure as Code (IaC) to ensure deployed resources match their intended configuration.

🎯 Purpose

Configuration drift occurs when live Azure resources diverge from their Infrastructure as Code definitions. This can happen through:

  • Manual changes via Azure Portal
  • Direct Azure CLI/PowerShell modifications
  • External automation or scripts
  • Azure policy enforcement
  • Resource auto-scaling or auto-updates

The Azure Configuration Drift Detector helps maintain IaC compliance by identifying these deviations quickly and clearly.

✨ Key Features

πŸ” Azure What-If Based Drift Detection

  • Azure-Native Comparison: Uses Azure's az deployment group what-if for authoritative drift detection
  • Intelligent Noise Suppression: Filters Azure platform behaviors with configurable ignore patterns
  • Multi-Resource Support: Works with any Azure resource type (VNets, Storage, Key Vault, App Services, NSGs, etc.)
  • Property-Level Comparison: Detects specific property changes with precise Expected vs Actual reporting
  • Complex Object Handling: Intelligent reporting for arrays and nested objects
  • External Module Support: Full support for Azure Container Registry modules (br: syntax) and Azure Verified Modules (AVM)

🎨 Type-Safe Bicep with User-Defined Types (UDTs)

  • Exported Types: Each Bicep module exports its own configuration types with @export()
  • Single Config Objects: Clean module interface with one config parameter per module
  • Full IntelliSense: Complete type checking and autocomplete in VS Code
  • DRY Architecture: Types defined once in modules, imported where needed
  • Compile-Time Validation: Catch configuration errors before deployment

πŸ“Š Clean, Human-Friendly Reporting

  • Suppressed Verbose Output: Azure what-if output hidden, showing only formatted results
  • Console: Clean, colorized terminal output with emojis
  • JSON: Structured data for automation and CI/CD integration
  • HTML: Browser-friendly reports with styling
  • Markdown: Documentation-ready format
  • Complex Object Messages: Clear explanations for array/object drift instead of raw JSON

πŸ”§ Automatic Drift Remediation

  • Autofix Mode: Automatically deploy Bicep template to fix detected drift with --autofix flag
  • Smart Deployment: Only deploys when actual drift is detected
  • Safe Execution: Provides detailed deployment feedback and error handling
  • Deployment Tracking: Generates unique deployment names with timestamps

πŸŽ›οΈ Modern Bicep Architecture

  • Modular Design: Separate modules for each resource type in bicep-modules/ directory
  • Bicepparam Support: Native .bicepparam file support for parameter management
  • Union Types: Type-safe SKU and configuration options using union types
  • Optional Parameters: Nullable fields with safe access operators and sensible defaults
  • Parameter Merging: Automatic merging of common parameters (location, tags) with config objects

πŸ”‡ Intelligent Drift Filtering

  • Noise Suppression: Advanced ignore system to filter out Azure platform behaviors and false positives
  • AVM Noise Filtering: Specialized suppression for Azure Verified Modules compliance properties
  • Resource-Specific Rules: Target specific resource types with conditional filtering
  • Global Patterns: Apply ignore rules across all resource types for common Azure properties
  • Conditional Logic: Rules that apply only when specific conditions are met (SKU tier, resource kind, etc.)
  • Configurable Paths: Support for custom ignore configuration files via --ignore-config
  • Pattern Matching: Flexible property path matching with wildcards and nested object support
  • Clear Feedback: Visual indicators showing which drifts are being ignored and why

πŸ“– Complete Drift Ignore Documentation - Comprehensive guide with examples and best practices

πŸš€ Quick Start

Prerequisites

  • .NET 8.0 SDK
  • Azure CLI (logged in with az login)
  • Bicep CLI

Installation

git clone <your-repo>
cd AzureDriftDetector
dotnet build

Basic Usage

# Detect drift using a Bicep template
dotnet run -- --bicep-file template.bicep --resource-group myResourceGroup

# Detect drift using a Bicepparam file
dotnet run -- --bicep-file template.bicepparam --resource-group myResourceGroup

# Detect drift and automatically fix it
dotnet run -- --bicep-file template.bicepparam --resource-group myResourceGroup --autofix

# Generate HTML report
dotnet run -- --bicep-file template.bicep --resource-group myResourceGroup --output Html

# Generate JSON report for automation
dotnet run -- --bicep-file template.bicep --resource-group myResourceGroup --output Json

# Use custom ignore configuration to suppress Azure platform noise
dotnet run -- --bicep-file template.bicep --resource-group myResourceGroup --ignore-config custom-ignore.json

# Works with external Azure Container Registry modules and Azure Verified Modules (AVM)
dotnet run -- --bicep-file template-with-external-modules.bicep --resource-group myResourceGroup --ignore-config drift-ignore.json

# See docs/DRIFT-IGNORE.md for comprehensive ignore configuration guide

πŸ“– Need to configure drift ignore rules? See our comprehensive Drift Ignore Configuration Guide with examples for common Azure services and best practices.

πŸ“‹ Example Scenarios

Scenario 1: Service Endpoint Drift

Template Definition:

subnets: [
  {
    name: subnetName
    properties: {
      addressPrefix: '10.0.0.0/24'
    }
  }
]

Manual Change in Portal: Added Microsoft.Storage service endpoint

Drift Detection Result:

πŸ”„ properties.subnets (Modified)
   Expected: ['myapp-subnet' (10.0.0.0/24)]
   Actual:   ['myapp-subnet' (10.0.0.0/24) [endpoints: Microsoft.Storage]]

Scenario 2: Network Security Group Rule Drift

Template Definition:

resource networkSecurityGroup 'Microsoft.Network/networkSecurityGroups@2023-04-01' = {
  name: 'myapp-nsg'
  properties: {
    securityRules: [
      {
        name: 'AllowHTTP'
        priority: 100
        access: 'Allow'
        direction: 'Inbound'
        protocol: 'Tcp'
        sourcePortRange: '*'
        destinationPortRange: '80'
      }
    ]
  }
}

Manual Change in Portal: Added SSH rule with priority 200

Drift Detection Result:

πŸ”„ properties.securityRules (Modified)
   Expected: "configured in template"
   Actual:   "differs in Azure (complex object/array)"

Scenario 3: Storage Account Tag Drift

Template Definition:

resource storageAccount 'Microsoft.Storage/storageAccounts@2023-05-01' = {
  tags: {
    Environment: 'test'
    Application: 'drifttest'
    ResourceType: 'Infrastructure'
  }
}

Manual Change: Tags modified to Environment: 'production' and added ManualTag: 'test'

Drift Detection Result:

πŸ”„ tags.Environment (Modified)
   Expected: "test"
   Actual:   "production"

❓ tags.ManualTag (Added)
   Expected: "not set"
   Actual:   "test"

❌ tags.ResourceType (Missing)
   Expected: "Infrastructure"
   Actual:   "removed"

Scenario 4: Missing Resource Detection

Template Definition:

resource networkSecurityGroup 'Microsoft.Network/networkSecurityGroups@2023-04-01' = {
  name: '${applicationName}-nsg'
  // ... configuration
}

Azure Reality: NSG was never deployed or was deleted

Drift Detection Result:

❌ resource (Missing)
   Expected: "exists"
   Actual:   "missing"

Note: Internally the detector interprets Azure what-if + (create) lines as a Missing drift when the resource is defined in the template but does not exist in the target Azure environment. This makes deleted or never-deployed resources visible in drift reports (see PR #71).

Scenario 5: Automatic Drift Remediation with --autofix

Template Definition:

resource networkSecurityGroup 'Microsoft.Network/networkSecurityGroups@2023-04-01' = {
  name: '${applicationName}-nsg'
  properties: {
    securityRules: [
      {
        name: 'AllowHTTP'
        properties: {
          protocol: 'Tcp'
          sourcePortRange: '*'
          destinationPortRange: '80'
          access: 'Allow'
          direction: 'Inbound'
          priority: 100
        }
      }
    ]
  }
}

Manual Change: Added SSH rule via Azure Portal

Drift Detection with Autofix:

dotnet run -- --bicep-file template.bicep --resource-group myRG --autofix

Output:

❌ Configuration drift detected!
πŸ”§ Attempting to fix drift by deploying template...
πŸš€ Deploying Bicep template to resource group: myRG
βœ… Deployment completed successfully!
βœ… Drift has been automatically fixed!
πŸ“¦ Deployment Name: drift-autofix-20251113-150351

Scenario 6: Conditional Deployment Support

Template Definition:

var deployKeyVault = false
resource keyVault 'Microsoft.KeyVault/vaults@2023-07-01' = if (deployKeyVault) {
  // ... configuration
}

Result: When deployKeyVault = false, the detector excludes the Key Vault from drift analysis, preventing false positives.

πŸ”— External Module Support

Azure Container Registry Integration

The tool provides comprehensive support for external Bicep modules from Azure Container Registry and Azure Verified Modules (AVM):

Supported Module Syntax

// Azure Container Registry modules
module myModule 'br:myregistry.azurecr.io/bicep/storage/account:v1.0.0' = { ... }

// Public Azure Verified Modules
module avm 'br/public:avm/res/storage/storage-account:0.9.1' = { ... }

// Private registry modules  
module private 'br:private.azurecr.io/modules/networking/vnet:latest' = { ... }

Key Features

  • Automatic Resolution: External modules resolved via Azure what-if analysis
  • No Manual Downloads: Modules processed automatically without local caching
  • Complex Dependencies: Handles module chains and nested external references
  • Mixed Templates: Supports templates combining external modules with direct resources

AVM Noise Suppression

Azure Verified Modules often set compliance properties that differ from Azure defaults, creating false positive drift alerts. The tool includes comprehensive ignore patterns:

{
  "resourceType": "Microsoft.Storage/storageAccounts", 
  "reason": "AVM modules set explicit compliance properties",
  "ignoredProperties": [
    "properties.customDomain.useSubDomainName",
    "properties.customDomain"
  ]
}

Note: Use the included drift-ignore.json configuration file with --ignore-config drift-ignore.json to suppress common AVM noise patterns

Example: Mixed External and Direct Resources

// External AVM storage module
module storageModule 'br:myregistry.azurecr.io/bicep/storage/storageaccount:v1.1.0' = {
  params: {
    config: {
      name: 'mystorageaccount'
      location: 'uksouth'
      sku: 'Standard_LRS'
    }
  }
}

// Direct Azure resource
resource networkSecurityGroup 'Microsoft.Network/networkSecurityGroups@2023-11-01' = {
  name: 'myapp-nsg'
  location: 'uksouth'
  properties: {
    securityRules: [
      {
        name: 'allow-http'
        properties: {
          protocol: 'Tcp'
          sourcePortRange: '*'
          destinationPortRange: '80'
          access: 'Allow'
          direction: 'Inbound'
          priority: 1000
        }
      }
    ]
  }
}

Drift Detection with Noise Filtering:

πŸ”‡ Ignoring drift: Microsoft.Storage/storageAccounts - properties.customDomain
πŸ”‡ Ignoring drift: Microsoft.Storage/storageAccounts/blobServices - properties.deleteRetentionPolicy
βœ… No configuration drift detected after filtering 4 ignored drift(s)

πŸ”‡ Drift Ignore Configuration

The drift detection system includes a comprehensive ignore mechanism to suppress noise caused by Azure platform behaviors beyond your control.

Purpose

The ignore functionality is specifically designed to filter out "noise" from:

  • Azure Resource Manager (ARM) automatically adding platform-managed properties
  • Azure Verified Modules (AVM) modifying resources during or after deployment
  • Azure platform services updating timestamps, provisioning states, capacity metrics, or internal references
  • Tier-specific behaviors where Basic/Free tiers don't support certain properties that Premium tiers do
  • Platform-managed state that occurs outside of your Bicep template configuration and control

When to Use Ignore Patterns

βœ… Use for platform behaviors you cannot control:

  • Azure-managed timestamps (lastModified, createdOn, etc.)
  • Provisioning states that change automatically
  • Service tier limitations (Basic Service Bus not supporting advanced properties)
  • Azure policy enforcement adding required tags/properties
  • Auto-scaling metrics and capacity values

❌ Don't ignore legitimate configuration drift:

  • Manual changes made via Azure Portal
  • Security configuration modifications
  • Resource property changes that should be in your template
  • Actual configuration drift that indicates compliance issues

Configuration Format

Ignore patterns are defined in JSON configuration files (default: drift-ignore.json):

{
  "ignorePatterns": {
    "description": "Suppress Azure platform noise",
    "resources": [
      {
        "resourceType": "Microsoft.ServiceBus/namespaces/queues",
        "reason": "Service Bus Basic tier doesn't support these properties - Azure platform behavior",
        "ignoredProperties": [
          "properties.autoDeleteOnIdle",
          "properties.defaultMessageTimeToLive",
          "properties.duplicateDetectionHistoryTimeWindow",
          "properties.maxMessageSizeInKilobytes"
        ]
      }
    ],
    "globalPatterns": [
      {
        "propertyPattern": "properties.provisioningState", 
        "reason": "Azure-managed provisioning state - not user configurable"
      },
      {
        "propertyPattern": "properties.*Time*",
        "reason": "Ignore all Azure-managed timestamp properties"
      },
      {
        "propertyPattern": "properties.*time*",
        "reason": "Ignore all Azure-managed lowercase timestamp properties"
      }
    ]
  }
}

Command Line Usage

# Use default ignore config (drift-ignore.json in current directory)
dotnet run -- --bicep-file template.bicep --resource-group myRG

# Use custom ignore configuration file
dotnet run -- --bicep-file template.bicep --resource-group myRG --ignore-config prod-ignore.json

# Use ignore config from different directory
dotnet run -- --bicep-file template.bicep --resource-group myRG --ignore-config configs/ignore.json

Pattern Matching Rules

  • Exact Match: "properties.autoDeleteOnIdle" matches exactly that property path
  • Wildcards: "properties.*Time*" matches any property containing "Time" (case-sensitive)
  • Resource Types: Support wildcards like "Microsoft.ServiceBus/*" for all Service Bus resource types
  • Global vs Resource-Specific: Global patterns apply to all resources, resource-specific patterns only apply to matching resource types

Real-World Example

Before implementing ignore patterns:

❌ Configuration drift detected in 13 resource(s) with 15 property difference(s).

πŸ”΄ Microsoft.ServiceBus/namespaces/queues - myqueue
   ❌ properties.autoDeleteOnIdle (Missing)
      Expected: "PT10675199DT2H48M5.4775807S"
      Actual:   null
   ❌ properties.defaultMessageTimeToLive (Missing) 
      Expected: "P14D"
      Actual:   null
   ❌ properties.maxMessageSizeInKilobytes (Missing)
      Expected: 1024
      Actual:   null

After implementing ignore patterns:

βœ… No configuration drift detected!
πŸ“‹ Filtered 12 ignored property differences
🎯 Focus on legitimate drift - noise suppressed

πŸ—οΈ Advanced Features

Azure What-If Integration

The drift detector leverages Azure's native what-if functionality for authoritative drift detection:

# Behind the scenes, the tool runs:
az deployment group what-if --resource-group dev --template-file samples/main-template.bicep --parameters samples/main-template.bicepparam

This provides:

  • βœ… Azure-Native Comparison: Uses Azure's deployment engine for authoritative drift detection
  • βœ… Intelligent Noise Suppression: Filters Azure platform behaviors with configurable ignore patterns
  • βœ… Comprehensive Analysis: Detects most configuration changes across resource types
  • βœ… Clean Output: Verbose what-if output suppressed, showing only formatted drift results

Type-Safe Bicep Modules

Modern Bicep architecture with exported types:

// bicep-modules/storage-account.bicep
@export()
type StorageAccountSku = 'Standard_LRS' | 'Standard_GRS' | 'Premium_LRS'

@export()
type StorageAccountConfig = {
  storageAccountName: string
  location: string?
  skuName: StorageAccountSku?
  // ... more fields
}

param storageAccountConfig StorageAccountConfig

resource storageAccount 'Microsoft.Storage/storageAccounts@2023-05-01' = {
  name: storageAccountConfig.storageAccountName
  location: storageAccountConfig.?location ?? resourceGroup().location
  // ...
}
// main-template.bicep
import {StorageAccountConfig} from 'bicep-modules/storage-account.bicep'

param storageConfig StorageAccountConfig

module storageModule 'bicep-modules/storage-account.bicep' = {
  params: {
    storageAccountConfig: union(storageConfig, {location: location, tags: tags})
  }
}

Bicepparam File Support

Clean parameter management with .bicepparam files:

// main-template.bicepparam
using 'main-template.bicep'

param storageConfig = {
  storageAccountName: 'mystorageacct'
  skuName: 'Standard_LRS'
  kind: 'StorageV2'
  minimumTlsVersion: 'TLS1_2'
}

param tags = {
  Environment: 'production'
  Application: 'myapp'
}

🎨 Sample Output

Console Output

πŸ” AZURE CONFIGURATION DRIFT DETECTION REPORT
============================================================
πŸ“… Detection Time: 2025-11-13 18:41:37 UTC
πŸ“Š Summary: Configuration drift detected in 2 resource(s) with 4 property difference(s).

❌ Configuration drift detected in 2 resource(s):

πŸ”΄ Microsoft.Storage/storageAccounts - drifttestsay6kt676i
   Resource ID:
   Property Drifts: 3

   πŸ”„ tags.environment (Modified)
      Expected: "test"
      Actual:   "production"

   ❓ tags.manualTag (Added)
      Expected: "not set"
      Actual:   "drift"

   ❌ tags.Application (Missing)
      Expected: "drifttest"
      Actual:   "removed"

πŸ”΄ Microsoft.Network/networkSecurityGroups - drifttest-nsg
   Resource ID:
   Property Drifts: 1

   πŸ”„ properties.securityRules (Modified)
      Expected: "configured in template"
      Actual:   "differs in Azure (complex object/array)"

JSON Output (for automation)

{
  "HasDrift": true,
  "ResourceDrifts": [
    {
      "ResourceType": "Microsoft.Network/virtualNetworks",
      "ResourceName": "myapp-vnet",
      "ResourceId": "/subscriptions/.../myapp-vnet",
      "PropertyDrifts": [
        {
          "PropertyPath": "properties.subnets",
          "ExpectedValue": "['myapp-subnet' (10.0.0.0/24)]",
          "ActualValue": "['myapp-subnet' (10.0.0.0/24) [endpoints: Microsoft.Storage]]",
          "Type": "Modified"
        }
      ]
    }
  ],
  "DetectedAt": "2025-11-11T17:59:42.123Z",
  "Summary": "Configuration drift detected in 2 resource(s) with 2 property difference(s)."
}

�️ Security & Quality Assurance

GitHub Advanced Security

This project uses GitHub's security features to ensure code quality and security:

  • CodeQL Analysis: Automated security vulnerability scanning
  • Dependency Scanning: Monitors for vulnerable dependencies
  • Secret Scanning: Prevents accidental credential commits

Note: For private repositories, GitHub Advanced Security requires enabling through repository settings. See Security Setup Guide for detailed instructions.

Automated CI/CD Pipeline

Every push triggers comprehensive validation:

  • βœ… Cross-platform builds (Ubuntu, macOS, Windows)
  • βœ… Code quality and formatting checks
  • βœ… Bicep template validation
  • βœ… Security analysis with CodeQL
  • βœ… Automated dependency updates

πŸ”§ Command Line Options

Usage: dotnet run -- [options]

Options:
  --bicep-file <path>        Path to the Bicep template file (required)
  --resource-group <name>    Azure resource group name (required) 
  --output <format>          Output format: Console (default), Json, Html, Markdown
  --autofix                  Automatically deploy template to fix detected drift
  --ignore-config <path>     Path to drift ignore configuration file (default: drift-ignore.json)
  --show-filtered            Show detailed reasons for filtered drift (audit mode)
  --simple-output            Use simple ASCII characters for CI/CD compatibility
  --help                     Show help information

πŸ›οΈ Architecture

AzureDriftDetector/
β”œβ”€β”€ Core/
β”‚   └── DriftDetector.cs          # Main orchestration logic with ignore integration
β”œβ”€β”€ Models/
β”‚   └── DriftModels.cs             # Data structures for drift results and ignore config
β”œβ”€β”€ Services/
β”‚   β”œβ”€β”€ AzureCliService.cs         # Azure CLI integration & deployments
β”‚   β”œβ”€β”€ BicepService.cs            # Bicep compilation & what-if integration
β”‚   β”œβ”€β”€ WhatIfJsonService.cs       # JSON-based what-if parsing (reliable)
β”‚   β”œβ”€β”€ ComparisonService.cs       # Legacy text-based parsing (deprecated)
β”‚   β”œβ”€β”€ DriftIgnoreService.cs      # Ignore pattern matching and drift filtering
β”‚   └── ReportingService.cs        # Multi-format output generation
β”œβ”€β”€ bicep-modules/                 # Modular Bicep templates
β”‚   β”œβ”€β”€ storage-account.bicep      # Storage with exported types
β”‚   β”œβ”€β”€ virtual-network.bicep      # VNet with exported types
β”‚   β”œβ”€β”€ network-security-group.bicep
β”‚   β”œβ”€β”€ app-service-plan.bicep
β”‚   β”œβ”€β”€ log-analytics-workspace.bicep
β”‚   └── key-vault.bicep
β”œβ”€β”€ docs/                          # Documentation
β”‚   β”œβ”€β”€ DRIFT-IGNORE.md           # Comprehensive drift ignore configuration guide
β”‚   β”œβ”€β”€ SECURITY-SETUP.md         # GitHub Advanced Security setup
β”‚   └── BICEP-BUILD.md            # Bicep module development guide
β”œβ”€β”€ drift-ignore.json              # Default ignore configuration for Azure platform noise
β”œβ”€β”€ samples/                       # Example Bicep templates and parameters
β”‚   β”œβ”€β”€ main-template.bicep        # Main template importing module types
β”‚   └── main-template.bicepparam   # Parameter configuration
└── Program.cs                     # CLI interface & dependency injection

Key Components

  • BicepService: Integrates Azure what-if for authoritative drift detection, handles bicepparam files
  • AzureCliService: Queries live Azure resources and executes deployments with proper error handling
  • WhatIfJsonService: Parses what-if JSON output for reliable drift detection with ARM expression filtering
  • ComparisonService: Legacy text-based parsing (deprecated, kept for reference)
  • DriftIgnoreService: Pattern matching engine for filtering Azure platform noise
  • ReportingService: Generates clean, actionable drift reports in multiple formats
  • Bicep Modules: Type-safe, reusable infrastructure components with exported configuration types

🎯 Use Cases

DevOps & CI/CD Integration

# Azure DevOps Pipeline
- task: DotNetCoreCLI@2
  displayName: 'Detect Configuration Drift'
  inputs:
    command: 'run'
    arguments: '-- --bicep-file $(Build.SourcesDirectory)/infrastructure/main.bicep --resource-group $(ResourceGroupName) --output Json'
    
- task: PublishTestResults@2
  condition: always()
  inputs:
    testResultsFormat: 'JUnit'
    testResultsFiles: 'drift-report-*.json'

Compliance Monitoring

  • Daily drift scans for production environments
  • Compliance reporting for audit requirements
  • Change management validation before deployments

Development Workflow

  • Pre-deployment validation to ensure clean state
  • Post-deployment verification to confirm successful deployment
  • Environment consistency checks across dev/staging/production

πŸ” Technical Details

Supported Azure Resource Types

  • βœ… Networking: Virtual Networks, Subnets, Network Security Groups, Application Gateways
  • βœ… Compute: App Service Plans, Function Apps, Virtual Machines
  • βœ… Storage: Storage Accounts, Blob containers, File shares
  • βœ… Messaging: Service Bus (Namespaces, Queues, Topics, Subscriptions)
  • βœ… Security: Key Vaults, Managed Identities
  • βœ… Data: SQL Databases, Cosmos DB, Redis Cache
  • βœ… Any other Azure resource type (generic support)

Drift Detection Capabilities

  • Azure What-If Based: Uses Azure's native deployment engine for authoritative drift detection
  • Property-level granularity: Identifies specific changed properties
  • Complex object support: Handles arrays, nested objects with human-friendly messages
  • Tag drift detection: Detects added, removed, and modified tags
  • Configurable filtering: Reduce noise with ignore patterns for Azure platform behaviors

Performance Characteristics

  • Fast what-if execution: Leverages Azure's optimized what-if engine
  • Clean output: Suppressed verbose Azure output for better UX
  • Memory efficient: Streaming text processing for what-if results
  • Fast execution: Typical runs complete in 10-30 seconds

🀝 Contributing

This project demonstrates advanced techniques for:

  • Azure resource management automation
  • Complex JSON schema comparison
  • Infrastructure as Code validation
  • Multi-format reporting systems

πŸ“„ Exit Codes

  • 0: No configuration drift detected
  • 1: Configuration drift detected or error occurred

Suitable for CI/CD pipelines and infrastructure validation workflows.

πŸ“ Changelog

v3.2.0 (2025-11-15) - Comprehensive Drift Ignore System πŸ”‡

Noise Reduction

πŸ”‡ Drift Ignore System

  • ✨ Configurable Ignore Patterns: JSON-based configuration for suppressing Azure platform noise
  • 🎯 Purpose-Built for AVM/Platform Behaviors: Specifically designed to filter out Azure Resource Manager and Azure Verified Module modifications beyond user control
  • πŸ“‹ Resource-Specific Rules: Target specific resource types with custom ignore patterns
  • 🌐 Global Pattern Support: Wildcards and pattern matching for broad timestamp/state filtering
  • πŸ–₯️ Command Line Integration: --ignore-config parameter for flexible configuration file paths
  • πŸ“Š Filtering Statistics: Reports showing how many false positives were suppressed

πŸš€ Enhanced Azure Resource Support

  • ✨ Service Bus Integration: Complete support for Namespaces, Queues, Topics, and Subscriptions
  • πŸ”§ Tier-Aware Configuration: Conditional properties based on Basic vs Standard/Premium Service Bus tiers
  • 🌐 Application Gateway Module: Full Azure Application Gateway Bicep module with exported types
  • πŸ—ƒοΈ Azure SQL Database: Complete SQL Database support with server and database configuration

⚑ Improved Drift Detection Accuracy

  • πŸ› Fixed What-If Symbol Interpretation: Correctly handle -, +, ~, = symbols in Azure what-if output
  • πŸ” Better Child Resource Handling: Enhanced detection for nested resources and complex object drift
  • πŸ“ˆ Real-World Impact: Reduced false positives from 13 to 1 in production scenarios

πŸ› οΈ Technical Architecture

  • πŸ†• DriftIgnoreService: New service for pattern matching and drift filtering
  • πŸ”§ Enhanced ComparisonService: Integrated ignore filtering with what-if parsing
  • πŸ“š Updated Documentation: Comprehensive ignore configuration guide and best practices

v3.0.0 (2025-11-13) - Major Architecture Overhaul πŸš€

Breaking Changes - Major Release

🎯 Azure What-If Integration

  • ✨ Authoritative Drift Detection: Migrated from manual JSON comparison to Azure's native az deployment group what-if command
  • βœ… Zero False Positives: Eliminated all false positives from ARM expression vs resolved value comparisons
  • 🎨 Clean Output: Suppressed verbose Azure what-if output, showing only formatted drift results
  • πŸ“Š Better Complex Object Handling: Human-friendly messages for array/object drift instead of raw JSON snippets

πŸ—οΈ Type-Safe Bicep Architecture

  • ✨ User-Defined Types (UDTs): Full Bicep type system with @export() decorators on all modules
  • πŸ“¦ Single Config Objects: Each module accepts one config parameter instead of multiple individual params
  • πŸ”§ Modular Structure: Separated all resources into bicep-modules/ directory with exported types
  • 🎯 DRY Principle: Types defined once in modules, imported in main template - no duplication
  • βœ… Compile-Time Validation: Full IntelliSense and type checking for all Bicep files

πŸ“ Bicepparam Support

  • ✨ Native .bicepparam Files: Full support for Bicep parameter files with using statements
  • πŸ” Automatic Reference Resolution: Extracts referenced template from bicepparam files
  • ⚑ Streamlined Parameters: Clean parameter management separate from template logic

🎨 Enhanced User Experience

  • πŸ“Š Improved Drift Messages: Clear "configured in template" vs "differs in Azure (complex object/array)" for complex changes
  • 🧹 Removed Duplicate Code: Eliminated redundant comparison logic in favor of what-if parsing
  • ⚑ Faster Execution: What-if-based approach is faster than manual JSON traversal
  • 🎯 Accurate Tag Detection: Precise detection of tag additions, removals, and modifications

πŸ”§ Technical Improvements

  • πŸ—οΈ Refactored BicepService: Now integrates what-if instead of building ARM templates
  • πŸ“ Enhanced ComparisonService: Parses what-if text output into structured drift results
  • πŸ§ͺ Process Management: Fixed deployment deadlock issues with proper stdout/stderr handling
  • πŸ—‚οΈ Module Organization: Clean separation of concerns with typed module interfaces

πŸ“š Module Updates

  • Storage Account: Exported StorageAccountConfig, StorageAccountSku, TlsVersion, etc.
  • Virtual Network: Exported VnetConfig, Subnet, EnableState
  • NSG: Exported NsgConfig, SecurityRule, AccessType, TrafficDirection, NetworkProtocol
  • App Service Plan: Exported AppServicePlanConfig, AppServicePlanSku
  • Log Analytics: Exported LogAnalyticsConfig, LogAnalyticsSku
  • Key Vault: Exported KeyVaultConfig, KeyVaultSku, PublicAccess

πŸ—‘οΈ Removed

  • ❌ Removed types.bicep - types now live with their modules (DRY principle)
  • ❌ Removed manual JSON comparison logic - replaced with what-if parsing
  • ❌ Removed --simple-output flag - no longer needed with clean what-if output

v2.1.0 (2025-11-11) - Major Accuracy Improvements

  • ✨ Enhanced Comparison Logic: Specialized handlers for NSG security rules, subnet arrays, and Log Analytics workspaces
  • πŸ› False Positive Elimination: Intelligent filtering of Azure-generated metadata (provisioningState, etag, id, etc.)
  • 🎨 Improved JSON Formatting: Human-readable console output with proper indentation and formatting
  • πŸ” Smart Array Detection: Automatic detection and specialized comparison for different array types
  • ⚑ Performance Optimizations: More efficient comparison algorithms for complex nested objects
  • πŸ“Š Enhanced Reporting: Better formatting for console output with base JSON formatting
  • πŸ§ͺ Comprehensive Testing: Validated with real Azure resources across multiple resource types

Previous Versions

  • v2.0.0 - Initial stable release with multi-resource support
  • v1.x - Beta versions with basic drift detection capabilities

πŸ“„ License

This project is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.

What this means:

  • βœ… Free to use for personal, educational, and internal business purposes
  • βœ… Free to modify and distribute modifications under the same license
  • ❌ Cannot be sold or used for commercial redistribution
  • πŸ“ Attribution required - please credit the original project

For businesses: You can use this tool internally within your organization for drift detection without any licensing fees. You just cannot package and sell it as a commercial product.

See the LICENSE file for full details or visit Creative Commons for more information.


Built with ❀️ for the Azure DevOps community