Azure Resource Graph Queries for Cost Optimization
Azure Resource Graph (ARG) enables fast, cross-subscription resource querying using KQL via az graph query. Use it to find orphaned resources, unused infrastructure, and optimization targets.
How to Query
Use the extension_cli_generate MCP tool to generate az graph query commands:
azure__extension_cli_generate
intent: "query Azure Resource Graph to <describe what you want to find>"
cli-type: "az"Or construct directly:
az graph query -q "<KQL>" --query "data[].{name:name, type:type}" -o table⚠️ Prerequisite:
az extension add --name resource-graph
Key Tables
| Table | Contains |
|---|---|
Resources | All ARM resources (name, type, location, properties, tags) |
ResourceContainers | Subscriptions, resource groups, management groups |
AdvisorResources | Cost and performance recommendations |
Cost Optimization Query Patterns
Find orphaned (unattached) managed disks:
Resources
| where type =~ 'microsoft.compute/disks'
| where isempty(managedBy)
| project name, resourceGroup, location, diskSizeGb=properties.diskSizeGB, sku=sku.nameFind unattached public IP addresses:
Resources
| where type =~ 'microsoft.network/publicipaddresses'
| where isempty(properties.ipConfiguration)
| project name, resourceGroup, location, sku=sku.nameFind orphaned network interfaces:
Resources
| where type =~ 'microsoft.network/networkinterfaces'
| where isempty(properties.virtualMachine)
| project name, resourceGroup, locationResource count by SKU/tier (spot oversized resources):
Resources
| where isnotempty(sku.name)
| summarize count() by type, tostring(sku.name)
| order by count_ descTag coverage for cost allocation:
Resources
| extend hasCostCenter = isnotnull(tags['CostCenter'])
| summarize total=count(), tagged=countif(hasCostCenter) by type
| extend coverage=round(100.0 * tagged / total, 1)
| order by total descFind idle load balancers (no backend pools):
Resources
| where type =~ 'microsoft.network/loadbalancers'
| where array_length(properties.backendAddressPools) == 0
| project name, resourceGroup, location, sku=sku.nameGet Advisor cost recommendations:
AdvisorResources
| where properties.category == 'Cost'
| project name, impact=properties.impact, description=properties.shortDescription.solutionTips
- Use
=~for case-insensitive type matching (resource types are lowercase) - Navigate properties with
properties.fieldName - Use
--first Nto limit result count - Use
--subscriptionsto scope to specific subscriptions - Cross-reference orphaned resources with cost data from Cost Management API