Firewall Rule Inline Diffing

See exactly which rules were added, modified, or removedβ€”not confusing index-based array diffs.

azurerm

When firewall network rule collections change, Terraform often shows confusing index-based diffs. tfplan2md understands the semantics of firewall rules and presents a clear table showing exactly what changed.

❌ Without tfplan2md

Raw Terraform Output
# module.network.azurerm_firewall_network_rule_collection.network_rules will be updated in-place
~ resource "azurerm_firewall_network_rule_collection" "network_rules" {
    name                = "network-rules"
    # (4 unchanged attributes hidden)

  - rule {
      - description           = "DNS to Azure" -> null
      - destination_addresses = [
          - "168.63.129.16",
        ] -> null
      - destination_ports     = [
          - "53",
        ] -> null
      - name                  = "allow-dns" -> null
      - protocols             = [
          - "UDP",
        ] -> null
      - source_addresses      = [
          - "10.1.1.0/24",
        ] -> null
    }
  - rule {
      - description           = "Legacy HTTP" -> null
      - destination_addresses = [
          - "10.1.3.0/24",
        ] -> null
      - destination_ports     = [
          - "80",
        ] -> null
      - name                  = "allow-web" -> null
      - protocols             = [
          - "TCP",
        ] -> null
      - source_addresses      = [
          - "10.1.1.0/24",
        ] -> null
    }
  + rule {
      + description           = "Secure web"
      + destination_addresses = [
          + "10.1.3.0/24",
        ]
      + destination_ports     = [
          + "443",
        ]
      + name                  = "allow-web-secure"
      + protocols             = [
          + "TCP",
        ]
      + source_addresses      = [
          + "10.1.1.0/24",
        ]
    }
  + rule {
      + description           = "Log ingestion"
      + destination_addresses = [
          + "10.1.5.0/24",
        ]
      + destination_ports     = [
          + "8080",
        ]
      + name                  = "allow-log-ingest"
      + protocols             = [
          + "TCP",
        ]
      + source_addresses      = [
          + "10.1.4.0/24",
        ]
    }
}

Which rule was added? Which was removed? Index-based diffs are confusing.

βœ… With tfplan2md

Firewall Network Rule Collection Output

πŸ”„ module.network.azurerm_firewall_network_rule_collection.network_rules

Collection: network-rules | Priority: 120 | Action: βœ… Allow

Rule Changes

Change Rule Name Protocols Source Addresses Destination Addresses Destination Ports Description
βž• allow-web-secure πŸ”— TCP 🌐 10.1.1.0/24 🌐 10.1.3.0/24 πŸ”Œ 443 Secure web
βž• allow-log-ingest πŸ”— TCP 🌐 10.1.4.0/24 🌐 10.1.5.0/24 πŸ”Œ 8080 Log ingestion
βž• allow-icmp-ping πŸ“‘ ICMP 🌐 10.1.1.0/24 🌐 10.1.4.0/24 ✳️ ICMP ping for network diagnostics
πŸ”„ allow-dns πŸ“¨ UDP - 🌐 10.1.1.0/24
+ 🌐 10.1.1.0/24, 🌐 10.1.2.0/24
🌐 168.63.129.16 πŸ”Œ 53 DNS to Azure
πŸ”„ allow-api πŸ”— TCP 🌐 10.1.1.0/24 - 🌐 10.1.2.0/24
+ 🌐 10.2.2.0/24
- πŸ”Œ 8443
+ πŸ”Œ 8443, πŸ”Œ 9443
API tier
❌ allow-web πŸ”— TCP 🌐 10.1.1.0/24 🌐 10.1.3.0/24 πŸ”Œ 80 Legacy HTTP
⏺️ allow-monitoring πŸ”— TCP 🌐 10.1.1.0/24 🌐 10.1.4.0/24 πŸ”Œ 443 Monitoring
### πŸ”„ module.network.azurerm_firewall_network_rule_collection.network_rules

**Collection:** `network-rules` | **Priority:** `120` | **Action:** `βœ… Allow`

#### Rule Changes

| Change | Rule Name | Protocols | Source Addresses | Destination Addresses | Destination Ports | Description |
| -------- | ----------- | ----------- | ------------------ | ---------------------- | ------------------- | ------------- |
| βž• | `allow-web-secure` | `πŸ”— TCP` | `🌐 10.1.1.0/24` | `🌐 10.1.3.0/24` | `πŸ”Œ 443` | `Secure web` |
| βž• | `allow-log-ingest` | `πŸ”— TCP` | `🌐 10.1.4.0/24` | `🌐 10.1.5.0/24` | `πŸ”Œ 8080` | `Log ingestion` |
| βž• | `allow-icmp-ping` | `πŸ“‘ ICMP` | `🌐 10.1.1.0/24` | `🌐 10.1.4.0/24` | `✳️` | `ICMP ping for network diagnostics` |
| πŸ”„ | `allow-dns` | πŸ“¨ UDP | <code style="display:block; white-space:normal; padding:0; margin:0;"><span style="background-color: #fff5f5; border-left: 3px solid #d73a49; color: #24292e; display: inline-block; padding-left: 8px; margin-left: 0;">- 🌐 10.1.1.0/24</span><br><span style="background-color: #f0fff4; border-left: 3px solid #28a745; color: #24292e; display: inline-block; padding-left: 8px; margin-left: 0;">+ 🌐 10.1.1.0/24<span style="background-color: #acf2bd; color: #24292e;">, 🌐 10.1.2.0/24</span></span></code> | 🌐 168.63.129.16 | πŸ”Œ 53 | `DNS to Azure` |
| πŸ”„ | `allow-api` | πŸ”— TCP | 🌐 10.1.1.0/24 | <code style="display:block; white-space:normal; padding:0; margin:0;"><span style="background-color: #fff5f5; border-left: 3px solid #d73a49; color: #24292e; display: inline-block; padding-left: 8px; margin-left: 0;">- 🌐 10.<span style="background-color: #ffc0c0; color: #24292e;">1</span>.2.0/24</span><br><span style="background-color: #f0fff4; border-left: 3px solid #28a745; color: #24292e; display: inline-block; padding-left: 8px; margin-left: 0;">+ 🌐 10.<span style="background-color: #acf2bd; color: #24292e;">2</span>.2.0/24</span></code> | <code style="display:block; white-space:normal; padding:0; margin:0;"><span style="background-color: #fff5f5; border-left: 3px solid #d73a49; color: #24292e; display: inline-block; padding-left: 8px; margin-left: 0;">- πŸ”Œ 8443</span><br><span style="background-color: #f0fff4; border-left: 3px solid #28a745; color: #24292e; display: inline-block; padding-left: 8px; margin-left: 0;">+ πŸ”Œ 8443<span style="background-color: #acf2bd; color: #24292e;">, πŸ”Œ 9443</span></span></code> | `API tier` |
| ❌ | `allow-web` | `πŸ”— TCP` | `🌐 10.1.1.0/24` | `🌐 10.1.3.0/24` | `πŸ”Œ 80` | `Legacy HTTP` |
| ⏺️ | `allow-monitoring` | `πŸ”— TCP` | `🌐 10.1.1.0/24` | `🌐 10.1.4.0/24` | `πŸ”Œ 443` | `Monitoring` |

Crystal clear: 3 added, 2 changed, 1 removed, 1 unchanged.

Key Features

  • Shows add/change/delete/unchanged status for each rule
  • Displays all rule properties in a scannable table
  • Works for all azurerm_firewall_network_rule_collection and azurerm_firewall_application_rule_collection resources
  • Automatically appliedβ€”no configuration needed

Learn More

This feature uses resource-specific templates to provide inline diffing for firewall rules.