TL/DR: The Azure CLI can be used to query data from Azure. For more information on how to use the Azure CLI query functionality, see the Azure CLI Query documentation.


The Azure CLI can be used to not only create, configure, and delete resources from Azure but to also query data from Azure. To do so, the Azure CLI uses the --query argument to run a JMESPath query against your Azure subscriptions. Querying Azure for resource properties can be quite helpful when writing scripts using the Azure CLI. For instance, you may want to get the IP address of an Azure Virtual Machine or Container Instance in order to perform some action on that resource.


This article includes a quick exercise that demonstrates several concepts with a final goal being to query a single resource property and storing the value of that property in a variable. This is demonstrated using Azure Container Instances (ACI). You do not need to have experience with ACI to complete the steps in this article, the concepts transfer to any Azure resource.


For quick access to the Azure CLI consider using the Azure Cloud Shell.


Create three Container Instances


Before digging into query syntax and operations, create a resource group using the az group create command and three container instances using the az container create command. The following bash script can be used to complete this.


# Create Resource Group
az group create --name myResourceGroup --location eastus

# Create three container instances
for ((i=0; i<3; ++i)); do az container create --resource-group myResourceGroup --name mycontainer$i --image microsoft/aci-helloworld --ip-address public; done


Output format


Before talking about the query command, lets discuss output format. By default, when any command is run using the Azure CLI, the output is returned JSON formatted. For example, run the az container list command. You should see that a JSON document is returned with the details of all container instances in your subscription.


$ az container list


While the JSON output is verbose, which is great, we may want to format the output a little more elegantly. We can do so by changing the output format. This article will focus on table and tsv format. For a complete list of Azure CLI output formats and a explanation of each, see Output format for Azure CLI commands.


Change the output type using the --output argument. In the following example the output type of table is used. You can see that while the output is not quite as verbose, it is easier to parse.


$ az container list --output table

Name          ResourceGroup    Status     Image                     IP:ports           Network    CPU/Memory       OsType    Location
------------  ---------------  ---------  ------------------------  -----------------  ---------  ---------------  --------  ----------
mycontainer0  myResourceGroup  Succeeded  microsoft/aci-helloworld    Public     1.0 core/1.5 gb  Linux     eastus
mycontainer1  myResourceGroup  Succeeded  microsoft/aci-helloworld  Public     1.0 core/1.5 gb  Linux     eastus
mycontainer2  myResourceGroup  Succeeded  microsoft/aci-helloworld  Public     1.0 core/1.5 gb  Linux     eastus


You can change the default output format for the CLI with the az configure command.


Azure CLI query


To start, lets return a single property of a single container instance using the az container show command. In the following example notice that the --query argument is called and that the name property is specified.


$ az container show -n mycontainer0 -g myResourceGroup --query name --output table



This works great when returning a single result. If however we want to pull the names of all container instances using the az container list command, we need to use the JAMESPath flatten operator  [ ]. In this example note that the az container list command is using [].name for the query value, which returns the names of all container instances.


$ az container list --query [].name --output table



If you wanted to return multiple properties, each of these can be comma delimited in square brackets.


$ az container list --query [].[name,location] --output table

Column1       Column2
------------  ---------
mycontainer0  eastus
mycontainer1  eastus
mycontainer2  eastus


To customize the column name we need to return a dictionary vs. an array using a JAMESPath multiSelect hash operator{ }. Returning a dictionary allows the property key to be set as the column label.


To achieve this, wrap the property selection in curly braces and name each property such as KeyValue:PropertyName. In the following example the key values are Name and Location.


$ az container list --query "[].{Name:name,Location:location}" --output table

Name          Location
------------  ----------
mycontainer0  eastus
mycontainer1  eastus
mycontainer2  eastus


Return value by index

Now let's say that you want to grab a specific object from an array by its index in that array. This can be done by specifying the index number in the square brackets. This can be helpful when looping through an array and performing an action on specific objects in that array. In the following example, the object at index 2 is returned.
$ az container list --query [2].name --output table

You can also return a slice of indexes. In this example object 0 until 2 are returned. In this case 0 and 1 are returned.
$ az container list --query [0:2].name --output table


Filter results on a value


In many cases we want to filter an array based on a value. This can be done using a JMESPath filter expression. In the following example only the container instances with a name containing mycontainer2 is returned.


$ az container list --query "[?contains(name, 'mycontainer2')]" --output table

Name          Location    ProvisioningState    RestartPolicy    OsType    ResourceGroup
------------  ----------  -------------------  ---------------  --------  ---------------
mycontainer2  eastus      Succeeded            Always           Linux     myResourceGroup


Store single property in a variable


Now let's put some of these concepts in play and find a specific container instances IP address and place that IP address into a variable.


We will start by returning the IP address of a container instance with the name mycontainer2.


$ az container list --query "[?contains(name, 'mycontainer2')].[ipAddress.ip]" --output table



However we only want the IP address and do not need the table formatting nor header. Instead of using table output, use tabbed separated values, or tsv. This returns only the IP address.


$ az container list --query "[?contains(name, 'mycontainer2')].[ipAddress.ip]" --output tsv


Now update the command to place the results into a variable. The following example works in bash.


$ ip=$(az container list --query "[?contains(name, 'mycontainer2')].[ipAddress.ip]" --output tsv)


If using PowerShell, the command would look similar to this.


PS $ip = $(az container list --query "[?contains(name, 'mycontainer2')].[ipAddress.ip]" --output tsv)


At this point, if we were writing a script to say perform some action against the container instance, we could reference this variable when needing the IP address of the container instance.

Super Contributor

I have a question about

--query [0:2].name 

 Would it also return the same container0 and 1 if you do [1:2]? Or is it just such format to always start with 0, but it returns only 2 values if 2 is the second number? But you said that it should return values from 0 through 2 and this would mean 0, 1, 2 (3 values, not two).


Oleg, thanks for the question. [0:2] returns two values, 0 through 2, so 0 and 1. So [1:2] would only return one item, mycontainer1 in the case of these examples.


I think the word 'through' may be subjective here. I will update the blog for clarity.

Hi Neil,


I think there is a better way when querying resources in your subscriptions - using Resource Graph, so you don't need to read via ARM resource providers and potentially hit the throttling limit in a large environment.


Thanks, Tao - for sure there are multiple ways to query resources. I have not used Resource Graph myself but know that it is very powerful and plan on taking some time to dig in.


Do you have an example where Resource Graph is used inside of script for populating values? For example, can I do something like this with Resource Graph? This creates a container instance, queries the IP address of that resource and stores it in a variable.


ip=$(az container create --name test555 --resource-group myResourceGroup --image microsoft/aci-helloworld --ip-address Public --query ipAddress.ip --output tsv)


Thanks a bunch for the comments.

Hi Neil,

I have few sample queries here: https://github.com/tyconsulting/ExpertsLiveUSA2019/blob/master/resourceGraph/DemoQuery.ps1


Resource Graph uses aliases just like Azure Policy definition. so as long as there is an alias referencing the resource type, you can query it. you can retrieve the list of aliases using REST API, PowerShell or Azure CLI: https://docs.microsoft.com/en-us/azure/governance/policy/concepts/definition-structure#aliases