Saving time with Azure Resource Graph

This year, at the Ignite conference, Microsoft announced Azure Resource Graph service. As we can read in the documentation, Azure Resource Graph is:

a service in Azure that is designed to extend Azure Resource Management by providing efficient and performant resource exploration with the ability to query at scale across all subscriptions and management groups so that you can effectively govern your environment. These queries provide the following capabilities:

  • Ability to query resources with complex filtering, grouping, and sorting by resource properties.
  • Ability to iteratively explore resources based on governance requirements and convert the resulting expression into a policy definition.
  • Ability to assess the impact of applying policies in a vast cloud environment.

What is Azure Resource Graph?

Azure Resource Manager sends data to a cache that exposes some information about resource (Resource name, ID, Type, Resource Group, Subscriptions, and Location). Normally we make calls to each resource provider and request these informations for each resource. It means not only much more calls to make but also a need to create a script which will handle that operation.

With Azure Resource Graph, we can access these informations directly, using complex query language we know, the Kusto query language.

How to use Azure Resource Graph?

To use Azure Resource Graph, you need at least Reader (RBAC) role on the resources you want to query.

To query Azure Resource Graph, you can use Azure CLI, PowerShell, SDK or REST API directly.

Sample queries

How much time we are saving?

In simple words, a lot. Let's consider a simple scenario with just 10 VMs in just one subscription. If we want to summarize Operating Systems we are using Without Azure Resource Graph, we need to call Azure Resource Manager for all the resources with resource type like Microsoft.Compute/virtualMachines and then iterate all VMs for storageProfile.osDisk.osType property. In Azure CLI it will be something like that:

for id in `az resource list --resource-type 'Microsoft.Compute/virtualMachines' --query '[].id' -o tsv`; do az resource show --ids $id --query 'properties.storageProfile.osDisk.osType'; done | uniq -c

The uniq -c command at the end is summarizing every unique OS type. The output of this script for my subscription is:

3 "Windows"
7 "Linux"

and it took a little bit more than 11s to complete.

With Azure Resource Graph I used az graph query command with simple Kusto query:

az graph query -q "where type =~ 'Microsoft.Compute/virtualMachines' | summarize count() by tostring(properties.storageProfile.osDisk.osType)" -s xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

The output of this command is:

    "count_": 7,
    "properties_storageProfile_osDisk_osType": "Linux"
    "count_": 3,
    "properties_storageProfile_osDisk_osType": "Windows"

and it took around 1.5s to complete.

As you can see, in graph query I have limited query to just one subscription - it's because Azure Resource Graph is returning results for all resources in all subscriptions we have access to. I have also noticed, that this rule is not true for subscriptions where we are external AAD users with RBAC roles - in that situation we are receiving "Access denied" message.


The response schema for ARG query is different than resource query. As an example, let's check a schema for query about a VM.


az vm show -g group -n VM0


If you are wondering what Aliases are, check here.

comments powered by Disqus