Testing Azure Policy Definitions: A Comprehensive Guide
- gs9074
- Sep 16
- 3 min read
Updated: Oct 28
Importance of Testing Azure Policy Definitions
Testing your Azure Policy definitions before switching from Audit to Deny or Modify is essential. Without a dry run, you can easily miss resources that should be compliant or accidentally block legitimate deployments. A structured testing approach can save time, avoid surprises, and give you confidence that your policy behaves as intended.
This guide shows how to validate Azure Policy logic using Azure Resource Graph queries and compare them with the policy evaluation captured by Azure Policy Insights. You will learn how to run these queries using the Azure CLI, the Azure portal, and PowerShell, so you can choose the tool that fits your workflow. While we build sample queries against tag conditions, the same approach works for properties like publicNetworkAccess or SKU.
Build the Expected Resource Set
Identifying Resources
First, identify which resources should match your policy conditions. Using Azure Resource Graph, you can filter by resource type and tag values (or other properties) to assemble the expected set. Replace the placeholders in this query with your own values:
```kusto
Resources
| where type =~ "Microsoft.Storage/storageAccounts"
| extend TagValue = tostring(tags['myTag'])
| where isnotempty(TagValue) and TagValue in~ (dynamic(['VALUE1','VALUE2']))
| project id, name, resourceGroup, subscriptionId
| join kind=leftanti (
PolicyResources
| where type =~ "Microsoft.PolicyInsights/PolicyStates"
| where properties.policyAssignmentName == "Your-Assignment-Name"
| summarize arg_max(properties."timestamp", *) by resourceId = tostring(properties.resourceId)
| project resourceId
) on $left.id == $right.resourceId
| project id, name, resourceGroup, subscriptionId
```
These resources satisfy your conditions but were not evaluated under the assignment. Common causes include wrong assignment scope, the wrong mode (use Indexed for tag and location policies), or incorrect parameters.
Common Issues
If you find resources that meet your criteria but were not evaluated, consider the following:
Wrong Assignment Scope: Ensure that the scope of your policy assignment is correct.
Incorrect Mode: For tag and location policies, use the Indexed mode.
Parameter Issues: Double-check your parameters for accuracy.
Running Queries with Azure CLI
You can run Resource Graph queries from your terminal with the Azure CLI. Here’s how:
```bash
az graph query --management-groups <yourManagementGroupId> --query "/ paste the query /" -o table
```
To trigger a policy compliance scan on demand (useful if you just assigned the policy), run:
```bash
az policy state trigger-scan --subscription <subscriptionId>
```
Running Queries in the Azure Portal
The Azure portal includes a Resource Graph Explorer that runs the same queries. Navigate to Azure Portal → Resource Graph Explorer. Select the management group or subscription at the top, paste your Kusto query into the query window, and click Run. Use the results grid to verify which resources are expected to match your policy or to inspect the difference set.
The policy compliance blade also shows evaluations, but it hides resources marked as Not applicable. The Resource Graph approach gives you full visibility and reproducibility.
Running Queries with PowerShell
PowerShell users can access Resource Graph and Policy Insights with the Az modules:
```powershell
Search-AzGraph -ManagementGroup <yourManagementGroupId> -Query "<query>" | Format-Table
Start-AzPolicyComplianceScan -Scope "/subscriptions/<subscriptionId>"
```
Use the same queries you defined earlier to assemble the expected set and join it against policy states. PowerShell’s pipeline makes it easy to export results to CSV for further analysis.
Classifying Every Resource
For a deeper analysis, you can build a single query that classifies every resource into buckets such as Expected, Not Expected, No Tag, Evaluated, and Not Evaluated. This helps you understand why a particular resource is missing from the compliance results and whether it falls outside your policy logic or simply wasn’t evaluated.
Understanding Resource Classification
Classifying resources allows for better visibility into compliance. Here’s a breakdown of each classification:
Expected: Resources that meet the policy criteria.
Not Expected: Resources that do not meet the policy criteria.
No Tag: Resources that lack the necessary tags.
Evaluated: Resources that were assessed against the policy.
Not Evaluated: Resources that were not assessed, possibly due to configuration issues.
Conclusion
Testing Azure Policy logic requires more than glancing at the compliance blade. By reproducing the policy rules with Azure Resource Graph, comparing the expected set with the actual evaluation, and exploring the difference, you gain a precise understanding of what your policy does. Whether you prefer the Azure portal, Azure CLI, or PowerShell, you now have the tools to validate policies confidently, adjust scopes and parameters, and proceed to enforce your standards.
By following this structured approach, you can ensure that your Azure policies are effective and compliant, ultimately leading to a more secure and well-managed cloud environment.
For more information on Azure Policy, visit Azure Policy Documentation.



Comments