Reacting to Azure Policy state change events

Azure Policy events enable applications to react to state changes. This integration is done without the need for complicated code or expensive and inefficient polling services. Instead, events are pushed through Azure Event Grid to subscribers such as Azure Functions, Azure Logic Apps, or even to your own custom HTTP listener. Critically, you only pay for what you use.

Azure Policy events are sent to the Azure Event Grid, which provides reliable delivery services to your applications through rich retry policies and dead-letter delivery. To learn more, see Event Grid message delivery and retry.

The common Azure Policy event scenario is tracking when the compliance state of a resource changes during policy evaluation. Event-based architecture is an efficient way to react to these changes instead of scanning the compliance state of resources on a fixed schedule.

Note

Azure Policy state change events are sent to Event Grid after an evaluation trigger finishes resource evaluation.

See Route policy state change events to Event Grid with Azure CLI for a full tutorial.

Event Grid model of sources and handlers

Available event types

Azure Policy emits the following event types:

Event type Description
Microsoft.PolicyInsights.PolicyStateCreated Raised when a policy compliance state is created.
Microsoft.PolicyInsights.PolicyStateChanged Raised when a policy compliance state is changed.
Microsoft.PolicyInsights.PolicyStateDeleted Raised when a policy compliance state is deleted.

Event properties

An event has the following top-level data:

Property Type Description
topic string Full resource path to the event source. This field isn't writeable. Event Grid provides this value.
subject string The fully qualified ID of the resource that the compliance state change is for, including the resource name and resource type. Uses the format, /subscriptions/<SubscriptionID>/resourceGroups/<ResourceGroup>/providers/<ProviderNamespace>/<ResourceType>/<ResourceName>
eventType string One of the registered event types for this event source.
eventTime string The time the event is generated based on the provider's UTC time.
id string Unique identifier for the event.
data object Azure Policy event data.
dataVersion string The schema version of the data object. The publisher defines the schema version.
metadataVersion string The schema version of the event metadata. Event Grid defines the schema of the top-level properties. Event Grid provides this value.

The data object has the following properties:

Property Type Description
timestamp string The time (in UTC) that the resource was scanned by Azure Policy. For ordering events, use this property instead of the top-level eventTime or time properties.
policyAssignmentId string The resource ID of the policy assignment.
policyDefinitionId string The resource ID of the policy definition.
policyDefinitionReferenceId string The reference ID for the policy definition inside the initiative definition, if the policy assignment is for an initiative. May be empty.
complianceState string The compliance state of the resource with respect to the policy assignment.
subscriptionId string The subscription ID of the resource.
complianceReasonCode string The compliance reason code. May be empty.

Example event

The following example shows the schema of a policy state created event scoped at the subscription level:

[{
    "id": "5829794FCB5075FCF585476619577B5A5A30E52C84842CBD4E2AD73996714C4C",
    "topic": "/subscriptions/<SubscriptionID>",
    "subject": "/subscriptions/<SubscriptionID>/resourceGroups/<ResourceGroup>/providers/<ProviderNamespace>/<ResourceType>/<ResourceName>",
    "data": {
        "timestamp": "2021-03-27T18:37:42.4496956Z",
        "policyAssignmentId": "<policy-assignment-scope>/providers/microsoft.authorization/policyassignments/<policy-assignment-name>",
        "policyDefinitionId": "<policy-definition-scope>/providers/microsoft.authorization/policydefinitions/<policy-definition-name>",
        "policyDefinitionReferenceId": "",
        "complianceState": "NonCompliant",
        "subscriptionId": "<subscription-id>",
        "complianceReasonCode": ""
    },
    "eventType": "Microsoft.PolicyInsights.PolicyStateCreated",
    "eventTime": "2021-03-27T18:37:42.5241536Z",
    "dataVersion": "1",
    "metadataVersion": "1"
}]

The schema for a policy state changed event scoped at the subscription level is similar:

[{
    "id": "5829794FCB5075FCF585476619577B5A5A30E52C84842CBD4E2AD73996714C4C",
    "topic": "/subscriptions/<SubscriptionID>",
    "subject": "/subscriptions/<SubscriptionID>/resourceGroups/<ResourceGroup>/providers/<ProviderNamespace>/<ResourceType>/<ResourceName>",
    "data": {
        "timestamp": "2021-03-27T18:37:42.4496956Z",
        "policyAssignmentId": "<policy-assignment-scope>/providers/microsoft.authorization/policyassignments/<policy-assignment-name>",
        "policyDefinitionId": "<policy-definition-scope>/providers/microsoft.authorization/policydefinitions/<policy-definition-name>",
        "policyDefinitionReferenceId": "",
        "complianceState": "NonCompliant",
        "subscriptionId": "<subscription-id>",
        "complianceReasonCode": ""
    },
    "eventType": "Microsoft.PolicyInsights.PolicyStateChanged",
    "eventTime": "2021-03-27T18:37:42.5241536Z",
    "dataVersion": "1",
    "metadataVersion": "1"
}]

The following example shows the schema of a policy state created event scoped at the management group level:

[{
    "id": "5829794FCB5075FCF585476619577B5A5A30E52C84842CBD4E2AD73996714C4C",
    "topic": "/tenants/<tenantId>/providers/Microsoft.Management/managementGroups/<managementGroupId>",
    "subject": "/subscriptions/<SubscriptionID>/resourceGroups/<ResourceGroup>/providers/<ProviderNamespace>/<ResourceType>/<ResourceName>",
    "data": {
        "timestamp": "2021-03-27T18:37:42.4496956Z",
        "policyAssignmentId": "<policy-assignment-scope>/providers/microsoft.authorization/policyassignments/<policy-assignment-name>",
        "policyDefinitionId": "<policy-definition-scope>/providers/microsoft.authorization/policydefinitions/<policy-definition-name>",
        "policyDefinitionReferenceId": "",
        "complianceState": "NonCompliant",
        "subscriptionId": "<subscription-id>",
        "complianceReasonCode": ""
    },
    "eventType": "Microsoft.PolicyInsights.PolicyStateCreated",
    "eventTime": "2021-03-27T18:37:42.5241536Z",
    "dataVersion": "1",
    "metadataVersion": "1"
}]

The schema for a policy state changed event scoped at the management group level is similar:

[{
    "id": "5829794FCB5075FCF585476619577B5A5A30E52C84842CBD4E2AD73996714C4C",
    "topic": "/tenants/<tenantId>/providers/Microsoft.Management/managementGroups/<managementGroupId>",
    "subject": "/subscriptions/<SubscriptionID>/resourceGroups/<ResourceGroup>/providers/<ProviderNamespace>/<ResourceType>/<ResourceName>",
    "data": {
        "timestamp": "2021-03-27T18:37:42.4496956Z",
        "policyAssignmentId": "<policy-assignment-scope>/providers/microsoft.authorization/policyassignments/<policy-assignment-name>",
        "policyDefinitionId": "<policy-definition-scope>/providers/microsoft.authorization/policydefinitions/<policy-definition-name>",
        "policyDefinitionReferenceId": "",
        "complianceState": "NonCompliant",
        "subscriptionId": "<subscription-id>",
        "complianceReasonCode": ""
    },
    "eventType": "Microsoft.PolicyInsights.PolicyStateChanged",
    "eventTime": "2021-03-27T18:37:42.5241536Z",
    "dataVersion": "1",
    "metadataVersion": "1"
}]

Practices for consuming events

Applications that handle Azure Policy events should follow these recommended practices:

  • Multiple subscriptions can be configured to route events to the same event handler, so don't assume events are from a particular source. Instead, check the topic of the message to ensure the policy assignment, policy definition, and resource the state change event is for.
  • Check the eventType and don't assume that all events you receive are the types you expect.
  • Use data.timestamp to determine the order of the events in Azure Policy, instead of the top-level eventTime or time properties.
  • Use the subject field to access the resource that had a policy state change.

Next steps

Learn more about Event Grid and give Azure Policy state change events a try: