Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
This article shows you how to monitor and track changes to Azure Firewall rule collection groups using Azure Resource Graph. Change tracking helps you maintain security compliance, audit configuration modifications, and troubleshoot issues by providing a detailed history of rule set modifications.
Azure Resource Graph provides change analysis data that helps you track when changes were detected on Azure Firewall rule collection groups. You can view property change details and query changes at scale across your subscription, management group, or tenant.
Change tracking for Azure Firewall rule collection groups enables you to:
- Monitor configuration changes: Track all modifications to firewall rules and policies
- Maintain compliance: Generate audit trails for security and compliance requirements
- Troubleshoot issues: Identify when changes were made that might affect connectivity
- Analyze trends: Understand patterns in rule modifications over time
Prerequisites
Before you can track rule set changes, verify that you meet the following requirements:
- You have an Azure Firewall with configured rule collection groups
- You have appropriate permissions to access Azure Resource Graph
- Your Azure Firewall is using Azure Firewall Policy (not classic rules)
Access Azure Resource Graph Explorer
To run change tracking queries, you need to access Azure Resource Graph Explorer:
- Sign in to the Azure portal
- Search for and select Resource Graph Explorer
- In the query window, you can run the change tracking queries described in the following sections
Basic change tracking query
Use this query to get a comprehensive view of all changes to Azure Firewall rule collection groups:
networkresourcechanges
| where properties contains "microsoft.network/firewallpolicies/rulecollectiongroups"
| extend parsedProperties = parse_json(properties)
| extend TargetResource = tostring(parsedProperties.targetResourceId),
Timestamp = todatetime(parsedProperties.changeAttributes.timestamp),
Changes = todynamic(parsedProperties.changes),
ChangeType = tostring(parsedProperties.changeType),
PreviousSnapshotId = tostring(parsedProperties.changeAttributes.previousResourceSnapshotId),
NewSnapshotId = tostring(parsedProperties.changeAttributes.newResourceSnapshotId),
CorrelationId = tostring(parsedProperties.changeAttributes.correlationId),
ChangesCount = toint(parsedProperties.changeAttributes.changesCount),
TenantId = tostring(tenantId),
Location = tostring(location),
SubscriptionId = tostring(subscriptionId),
ResourceGroup = tostring(resourceGroup),
FirewallPolicyName = extract('/firewallPolicies/([^/]+)/', 1, tostring(id))
| mv-expand ChangeKey = bag_keys(Changes)
| extend ChangeDetails = todynamic(Changes[tostring(ChangeKey)])
| extend RuleCollectionName = extract('properties\\.ruleCollections\\["([^"]+)"\\]', 1, tostring(ChangeKey))
| where isnotempty(RuleCollectionName)
| summarize Changes = make_list(pack("ChangeKey", ChangeKey, "PreviousValue", tostring(ChangeDetails.previousValue), "NewValue", tostring(ChangeDetails.newValue)))
by Timestamp = format_datetime(Timestamp, 'yyyy-MM-dd HH:mm:ss'),
TenantId,
SubscriptionId,
ResourceGroup,
Location,
TargetResource,
FirewallPolicyName,
RuleCollectionName,
ChangeType,
PreviousSnapshotId,
NewSnapshotId,
CorrelationId,
ChangesCount
| project Timestamp,
TenantId,
SubscriptionId,
ResourceGroup,
Location,
TargetResource,
FirewallPolicyName,
RuleCollectionName,
ChangeType,
PreviousSnapshotId,
NewSnapshotId,
CorrelationId,
ChangesCount,
Changes
| order by Timestamp desc
Understanding the query results
The change tracking query returns the following information for each detected change:
| Field | Description |
|---|---|
| Timestamp | When the change occurred |
| SubscriptionId | Azure subscription containing the firewall |
| ResourceGroup | Resource group containing the firewall policy |
| FirewallPolicyName | Name of the affected firewall policy |
| RuleCollectionName | Name of the affected rule collection |
| ChangeType | Type of change (Create, Update, Delete) |
| ChangesCount | Number of properties changed |
| Changes | Detailed list of what changed, including previous and new values |
| CorrelationId | Unique identifier linking related changes |
Filter changes by time period
To focus on recent changes, you can add a time filter to your query:
networkresourcechanges
| where properties contains "microsoft.network/firewallpolicies/rulecollectiongroups"
| where todatetime(properties.changeAttributes.timestamp) >= ago(7d) // Last 7 days
// ... rest of query
Filter by specific firewall policy
To track changes for a specific firewall policy:
networkresourcechanges
| where properties contains "microsoft.network/firewallpolicies/rulecollectiongroups"
| where id contains "/firewallPolicies/your-policy-name"
// ... rest of query
Set up automated monitoring
For continuous monitoring, consider setting up:
- Scheduled queries: Use Azure Logic Apps or Azure Automation to run queries on a schedule
- Alerts: Create Azure Monitor alerts based on change patterns
- Reports: Export results to storage or visualization tools for reporting
Best practices
When implementing rule set change tracking:
- Regular monitoring: Set up regular query execution to catch changes promptly
- Retention policies: Plan for long-term storage of change data for compliance
- Access control: Limit access to change tracking data based on security requirements
- Integration: Consider integrating with your existing SIEM or monitoring tools
Troubleshooting
If you don't see expected changes in your results:
- Verify that you're using Azure Firewall Policy (not classic rules)
- Check that the time period in your query covers when changes occurred
- Ensure you have the necessary permissions to access Azure Resource Graph
- Confirm that the resource names in your filters are correct