Como consultar a saída de comandos da CLI do Azure usando uma consulta JMESPath

A CLI do Azure usa o parâmetro --query para executar uma consulta JMESPath nos resultados dos comandos. JMESPath é uma linguagem de consulta do JSON, permitindo que você selecione e modifique os dados na saída da CLI.

Todos os comandos na CLI do Azure dão suporte ao --query parâmetro. Este artigo aborda como usar os recursos do JMESPath e dá exemplos de consultas. Saiba mais sobre os conceitos do JMESPath que são úteis para consultas na guia Conceitos. Veja exemplos de consultas JMESPath na guia Exemplos.

A CLI do Azure usa consultas para selecionar e modificar a saída dos respectivos comandos. As consultas são executadas no lado do cliente no objeto JSON retornado do comando da CLI do Azure antes das formatações de exibição.

Os caracteres de escape necessários em consultas variam em ambientes diferentes. É recomendável executar consultas no Azure Cloud Shell ou no cmd porque esses shells exigem menos caracteres de escape. Para garantir que os exemplos de consulta estejam sintaticamente corretos, selecione a guia do shell que você está usando.

Dicionário e lista dos resultados da CLI

Os resultados do comando da CLI são tratados primeiro como JSON para consultas, mesmo quando o formato de saída é algo diferente de JSON. Os resultados da CLI são uma matriz JSON ou um dicionário. Matrizes são sequências de objetos que podem ser indexados, e dicionários são objetos não ordenados acessados com chaves.

Este é um exemplo de uma matriz:

[ 
  1,
  2,
  3
]

Este é um exemplo de um dicionário:

{
  "isRunning": false,
  "time": "12:00",
  "number": 1
}

Os comandos que poderiam retornar mais de um objeto retornam uma matriz, e os comandos que sempre retornam apenas um objeto retornam um dicionário.

Obter propriedades em um dicionário

Trabalhando com os resultados do dicionário, você pode acessar as propriedades no nível superior com apenas a chave. O caractere . (subexpressão) é usado para acessar as propriedades dos dicionários aninhados. Antes de conhecer as consultas, examine a saída não modificada do comando az vm show:

az vm show --resource-group QueryDemo --name TestVM

O comando gera um dicionário. Parte do conteúdo foi omitida.

{
  "additionalCapabilities": null,
  "availabilitySet": null,
  "diagnosticsProfile": {
    "bootDiagnostics": {
      "enabled": true,
      "storageUri": "https://xxxxxx.blob.core.windows.net/"
    }
  },
  ...
  "osProfile": {
    "adminPassword": null,
    "adminUsername": "azureuser",
    "allowExtensionOperations": true,
    "computerName": "TestVM",
    "customData": null,
    "linuxConfiguration": {
      "disablePasswordAuthentication": true,
      "provisionVmAgent": true,
      "ssh": {
        "publicKeys": [
          {
            "keyData": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDMobZNJTqgjWn/IB5xlilvE4Y+BMYpqkDnGRUcA0g9BYPgrGSQquCES37v2e3JmpfDPHFsaR+CPKlVr2GoVJMMHeRcMJhj50ZWq0hAnkJBhlZVWy8S7dwdGAqPyPmWM2iJDCVMVrLITAJCno47O4Ees7RCH6ku7kU86b1NOanvrNwqTHr14wtnLhgZ0gQ5GV1oLWvMEVg1YFMIgPRkTsSQKWCG5lLqQ45aU/4NMJoUxGyJTL9i8YxMavaB1Z2npfTQDQo9+womZ7SXzHaIWC858gWNl9e5UFyHDnTEDc14hKkf1CqnGJVcCJkmSfmrrHk/CkmF0ZT3whTHO1DhJTtV stramer@contoso",
            "path": "/home/azureuser/.ssh/authorized_keys"
          }
        ]
      }
    },
    "secrets": [],
    "windowsConfiguration": null
  },
  ....
}

O comando a seguir obtém as chaves SSH públicas autorizadas para conectar a VM adicionando uma consulta:

az vm show --resource-group QueryDemo --name TestVM --query "osProfile.linuxConfiguration.ssh.publicKeys"
[
  {
    "keyData": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDMobZNJTqgjWn/IB5xlilvE4Y+BMYpqkDnGRUcA0g9BYPgrGSQquCES37v2e3JmpfDPHFsaR+CPKlVr2GoVJMMHeRcMJhj50ZWq0hAnkJBhlZVWy8S7dwdGAqPyPmWM2iJDCVMVrLITAJCno47O4Ees7RCH6ku7kU86b1NOanvrNwqTHr14wtnLhgZ0gQ5GV1oLWvMEVg1YFMIgPRkTsSQKWCG5lLqQ45aU/4NMJoUxGyJTL9i8YxMavaB1Z2npfTQDQo9+womZ7SXzHaIWC858gWNl9e5UFyHDnTEDc14hKkf1CqnGJVcCJkmSfmrrHk/CkmF0ZT3whTHO1DhJTtV stramer@contoso",
    "path": "/home/azureuser/.ssh/authorized_keys"
  }
]

As cadeias de caracteres do URI diferenciam maiúsculas de minúsculas. Por exemplo, se 'osProfile' for alterado para 'OsProfile' na consulta acima, não serão retornados os resultados corretos.

Obter vários valores

Para obter mais de uma propriedade, coloque as expressões separadas por vírgula entre colchetes [ ] (uma lista de seleção múltipla). O seguinte comando obtém o nome da VM, o usuário administrador e a chave SSH de uma só vez:

az vm show --resource-group QueryDemo --name TestVM --query "[name, osProfile.adminUsername, osProfile.linuxConfiguration.ssh.publicKeys[0].keyData]"
[
  "TestVM",
  "azureuser",
  "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDMobZNJTqgjWn/IB5xlilvE4Y+BMYpqkDnGRUcA0g9BYPgrGSQquCES37v2e3JmpfDPHFsaR+CPKlVr2GoVJMMHeRcMJhj50ZWq0hAnkJBhlZVWy8S7dwdGAqPyPmWM2iJDCVMVrLITAJCno47O4Ees7RCH6ku7kU86b1NOanvrNwqTHr14wtnLhgZ0gQ5GV1oLWvMEVg1YFMIgPRkTsSQKWCG5lLqQ45aU/4NMJoUxGyJTL9i8YxMavaB1Z2npfTQDQo9+womZ7SXzHaIWC858gWNl9e5UFyHDnTEDc14hKkf1CqnGJVcCJkmSfmrrHk/CkmF0ZT3whTHO1DhJTtV stramer@contoso"
]

Esses valores são listados na matriz de resultados na ordem em que foram fornecidos na consulta. Como o resultado é uma matriz, não há nenhuma chave associada a ele. Para obter um dicionário em vez de uma matriz, confira a seção abaixo.

Renomear as propriedades em uma consulta

Para obter um dicionário, em vez de uma matriz, ao consultar diversos valores, use o operador { } (hash de seleção múltipla). O formato de um hash de seleção múltipla é {displayName:JMESPathExpression, ...}. displayName será a cadeia de caracteres mostrada na saída e JMESPathExpression é a expressão do JMESPath a avaliar. Modifique o exemplo da última seção alterando a lista de seleção múltipla para um hash:

Observação

Se você optar por usar um espaço em um novo nome de coluna, como VM name em vez de , as regras de VMNamecitação serão alteradas no Bash e no PowerShell. Consulte Espaços de passagem nos parâmetros da CLI do Azure para obter exemplos.

az vm show --resource-group QueryDemo --name TestVM --query "{VMName:name, admin:osProfile.adminUsername, sshKey:osProfile.linuxConfiguration.ssh.publicKeys[0].keyData}"
{
  "VMName": "TestVM",
  "admin": "azureuser",
  "ssh-key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDMobZNJTqgjWn/IB5xlilvE4Y+BMYpqkDnGRUcA0g9BYPgrGSQquCES37v2e3JmpfDPHFsaR+CPKlVr2GoVJMMHeRcMJhj50ZWq0hAnkJBhlZVWy8S7dwdGAqPyPmWM2iJDCVMVrLITAJCno47O4Ees7RCH6ku7kU86b1NOanvrNwqTHr14wtnLhgZ0gQ5GV1oLWvMEVg1YFMIgPRkTsSQKWCG5lLqQ45aU/4NMJoUxGyJTL9i8YxMavaB1Z2npfTQDQo9+womZ7SXzHaIWC858gWNl9e5UFyHDnTEDc14hKkf1CqnGJVcCJkmSfmrrHk/CkmF0ZT3whTHO1DhJTtV stramer@contoso"
}

Obter propriedades em uma matriz

Uma matriz não tem nenhuma propriedade, mas pode ser indexada. Esse recurso é mostrado no último exemplo com a expressão publicKeys[0], que obtém o primeiro elemento da matriz publicKeys. Não há garantia de que a saída da CLI seja ordenada, portanto, evite usar a indexação, a menos que você tenha certeza da ordem ou não se importe com o elemento obtido. Para acessar as propriedades dos elementos em uma matriz, execute uma destas duas operações: nivelamento ou filtragem. Esta seção aborda como nivelar uma matriz.

O nivelamento de uma matriz é feito com o operador [] do JMESPath. Todas as expressões após o operador [] são aplicadas em cada elemento na matriz atual. Se [] aparecer no início da consulta, ele nivelará o resultado do comando da CLI. Os resultados de az vm list podem ser examinados com esse recurso. A seguinte consulta obtém o nome, o SO e o nome do administrador de cada VM em um grupo de recursos:

az vm list --resource-group QueryDemo --query "[].{Name:name, OS:storageProfile.osDisk.osType, admin:osProfile.adminUsername}"
[
  {
    "Name": "Test-2",
    "OS": "Linux",
    "admin": "sttramer"
  },
  {
    "Name": "TestVM",
    "OS": "Linux",
    "admin": "azureuser"
  },
  {
    "Name": "WinTest",
    "OS": "Windows",
    "admin": "winadmin"
  }
]

Qualquer matriz pode ser nivelada, não apenas o resultado de alto nível retornado pelo comando. Na última seção, a expressão osProfile.linuxConfiguration.ssh.publicKeys[0].keyData foi usada para obter a chave SSH pública para entrar. Para obter cada chave SSH pública, a expressão pode ser escrita como osProfile.linuxConfiguration.ssh.publicKeys[].keyData. Esta expressão de consulta nivela a matriz osProfile.linuxConfiguration.ssh.publicKeys e executa a expressão keyData em cada elemento:

az vm show --resource-group QueryDemo --name TestVM --query "{VMName:name, admin:osProfile.adminUsername, sshKeys:osProfile.linuxConfiguration.ssh.publicKeys[].keyData }"
{
  "VMName": "TestVM",
  "admin": "azureuser",
  "sshKeys": [
    "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDMobZNJTqgjWn/IB5xlilvE4Y+BMYpqkDnGRUcA0g9BYPgrGSQquCES37v2e3JmpfDPHFsaR+CPKlVr2GoVJMMHeRcMJhj50ZWq0hAnkJBhlZVWy8S7dwdGAqPyPmWM2iJDCVMVrLITAJCno47O4Ees7RCH6ku7kU86b1NOanvrNwqTHr14wtnLhgZ0gQ5GV1oLWvMEVg1YFMIgPRkTsSQKWCG5lLqQ45aU/4NMJoUxGyJTL9i8YxMavaB1Z2npfTQDQo9+womZ7SXzHaIWC858gWNl9e5UFyHDnTEDc14hKkf1CqnGJVcCJkmSfmrrHk/CkmF0ZT3whTHO1DhJTtV stramer@contoso\n"
  ]
}

Filtrar matrizes com expressões boolianas

A outra operação usada para obter dados de uma matriz é a filtragem. A filtragem é feita com o operador [?...] do JMESPath. Esse operador usa um predicado como conteúdo. Um predicado é qualquer instrução, incluindo propriedades boolianas, que pode ser avaliada como true ou false. As expressões em que o predicado é avaliado como true são incluídas na saída.

A primeira consulta demonstra como listar os nomes de todas as assinaturas do Azure conectadas à conta cuja propriedade isDefault é verdadeira. A segunda e a terceira consultas mostram duas maneiras diferentes de listar todas as assinaturas cuja propriedade isDefault é falsa.

# Boolean values are assumed to be true, so you can directly evaluate the isDefault property to return the default subscription.
az account list --query "[?isDefault].name"

# To check if a Boolean property is false, you can use the comparison operator == or the logical operator !.
az account list --query '[?!isDefault].name'
az account list --query "[?isDefault == \`false\`].name"

JMESPath oferece a comparação padrão e os operadores lógicos. Eles incluem <, <=, >, >=, == e !=. JMESPath também dá suporte às operações lógicas e (&&) ou (||), e não (!). Expressões podem ser agrupadas entre parênteses, permitindo expressões de predicado mais complexas. Para obter mais detalhes sobre predicados e operações lógicas, confira a especificação do JMESPath.

Na última seção, nivelamos uma matriz para obter a lista completa de todas as VMs em um grupo de recursos. Usando filtros, essa saída pode ser restrita apenas às VMs do Linux:

az vm list --resource-group QueryDemo --query "[?storageProfile.osDisk.osType=='Linux'].{Name:name,  admin:osProfile.adminUsername}" --output table
Name    Admin
------  ---------
Test-2  sttramer
TestVM  azureuser

Você também pode filtrar valores numéricos, como o tamanho do disco do sistema operacional. O exemplo a seguir demonstra como filtrar a lista de VMs para exibir aquelas com um tamanho de disco igual ou superior a 50 GB.

az vm list --resource-group QueryDemo --query "[?storageProfile.osDisk.diskSizeGb >=\`50\`].{Name:name,  admin:osProfile.adminUsername, DiskSize:storageProfile.osDisk.diskSizeGb }" --output table
Name     Admin     DiskSize
-------  --------  --------
WinTest  winadmin  127

Para matrizes grandes, pode ser mais rápido aplicar o filtro antes de selecionar os dados.

Importante

No JMESPath, as cadeias de caracteres sempre ficam entre aspas simples (') ou caracteres de escape (`). Se você usar aspas duplas como parte de uma cadeia de caracteres em um predicado de filtro, obterá uma saída vazia.

Funções JMESPath

O JMESPath também tem funções internas que permitem fazer consultas mais complexas e modificar a saída da consulta. Esta seção se concentra no uso de funções JMESPath para criar consultas enquanto a seção Como manipular a saída com funções demonstra como usar funções para modificar a saída.

As expressões são avaliadas antes que a função seja chamada, portanto, os próprios argumentos podem ser expressões JMESPath. Os seguintes exemplos demonstram isso usando contains(string, substring), o que verifica se uma cadeia de caracteres contém uma substring. Este comando localiza todas as VMs que usam o armazenamento SSD para o disco do SO:

az vm list --resource-group QueryDemo --query "[?contains(storageProfile.osDisk.managedDisk.storageAccountType,'SSD')].{Name:name, Storage:storageProfile.osDisk.managedDisk.storageAccountType}"
[
  {
    "Name": "TestVM",
    "Storage": "StandardSSD_LRS"
  },
  {
    "Name": "WinTest",
    "Storage": "StandardSSD_LRS"
  }
]

Expressões de barra vertical

Da mesma que forma que | é usado na linha de comando, | pode ser usado nas consultas JMESPath para aplicar expressões a resultados de consulta intermediários. Também podemos usar | para dividir consultas complexas em subexpressões mais simples. Para reduzir a consulta da seção anterior, use | para aplicar o filtro depois de nivelar e selecionar dados.

az vm list --resource-group QueryDemo --query "[].{Name:name, Storage:storageProfile.osDisk.managedDisk.storageAccountType} | [? contains(Storage,'SSD')]"
[
  {
    "Name": "TestVM",
    "Storage": "StandardSSD_LRS"
  },
  {
    "Name": "WinTest",
    "Storage": "StandardSSD_LRS"
  }
]

Confira a Especificação do JMESPath - Funções Internas para obter a lista completa de funções.

Como manipular a saída com funções

As funções do JMESPath também têm outra finalidade, que é operar nos resultados de uma consulta. Qualquer função que retorna um valor não booliano altera o resultado de uma expressão. Por exemplo, você pode classificar os dados por um valor de propriedade com sort_by(array, &sort_expression). O JMESPath usa um operador especial, &, para as expressões que devem ser avaliadas posteriormente como parte de uma função. O exemplo a seguir mostra como classificar uma lista de VMs pelo tamanho de disco do SO:

az vm list --resource-group QueryDemo --query "sort_by([].{Name:name, Size:storageProfile.osDisk.diskSizeGb}, &Size)" --output table
Name     Size
-------  ------
Test-2   30
TestVM   32
WinTest  127

Confira a Especificação do JMESPath - Funções Internas para obter a lista completa de funções.

Formatação de resultados da consulta

A CLI do Azure usa JSON como formato de saída padrão, porém formatos de saída diferentes podem ser mais adequados a uma consulta, dependendo da finalidade e dos resultados. Observe que as consultas são sempre executadas na saída JSON primeiro e depois formatadas.

Esta seção abordará a formatação tsv e table e alguns casos de uso de cada formato. Para obter mais informações sobre formatos de saída, confira Formatos de saída para comandos da CLI do Azure.

O formato de saída TSV

O formato de saída tsv retorna valores separados por tabulação e nova linha sem formatação, chaves ou outros símbolos adicionais. Esse formato é útil quando a saída é armazenada em um parâmetro e usada em outro comando.

Um caso de uso de formatação tsv são as consultas que recuperam um valor de um comando da CLI, como uma ID de recurso ou um nome de recurso do Azure, e armazenam o valor em uma variável de ambiente local. Por padrão, os resultados são retornados no formato JSON, o que pode ser um problema ao lidar com cadeias de caracteres JSON que estão entre os caracteres " . As aspas podem não ser interpretadas pelo shell quando a saída do comando é atribuída diretamente à variável de ambiente. Veja isso no seguinte exemplo que atribui um resultado de consulta a uma variável de ambiente:

USER=$(az vm show --resource-group QueryDemo --name TestVM --query "osProfile.adminUsername")
echo $USER
"azureuser"

Para evitar a colocação de valores retornados entre informações de tipo, use a formatação tsv, como demonstrado na seguinte consulta:

USER=$(az vm show --resource-group QueryDemo --name TestVM --query "osProfile.adminUsername" --output tsv)
echo $USER
azureuser

Formato de saída da tabela

O formato table imprime a saída como uma tabela ASCII, facilitando a leitura e a análise. Nem todos os campos são incluídos na tabela. Por isso, é melhor usar esse formato como uma visão geral dos dados que possa ser pesquisada manualmente. Os campos que não são incluídos na tabela, ainda podem ser filtrados durante uma consulta.

Observação

Algumas chaves são filtradas e não são impressas na exibição da tabela. Essas chaves são id, type e etag. Para ver esses valores, você pode alterar o nome da chave em um hash de seleção múltipla.

az vm show --resource-group QueryDemo --name TestVM --query "{objectID:id}" --output table

Podemos usar uma consulta anterior para demonstrar isso. A consulta original retornou um objeto JSON que contém o nome, o sistema operacional e o nome do administrador de cada VM no grupo de recursos:

az vm list --resource-group QueryDemo --query "[].{Name:name, OS:storageProfile.osDisk.osType, admin:osProfile.adminUsername}"
[
  {
    "Name": "Test-2",
    "OS": "Linux",
    "admin": "sttramer"
  },
  {
    "Name": "TestVM",
    "OS": "Linux",
    "admin": "azureuser"
  },
  {
    "Name": "WinTest",
    "OS": "Windows",
    "admin": "winadmin"
  }
]

Quando a combinados com o formato de saída --output table, os nomes de colunas correspondem ao valor displayKey do hash de seleção múltipla, facilitando a busca de informações:

az vm list --resource-group QueryDemo --query "[].{Name:name, OS:storageProfile.osDisk.osType, Admin:osProfile.adminUsername}" --output table
Name     OS       Admin
-------  -------  ---------
Test-2   Linux    sttramer
TestVM   Linux    azureuser
WinTest  Windows  winadmin

Próximas etapas

Para saber mais sobre as consultas JMESPath, consulte Tutorial do JMESPath.

Para saber mais sobre outros conceitos da CLI do Azure mencionados neste artigo, confira: