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

A CLI do Azure usa o --query parâmetro para executar uma consulta JMESPath nos resultados dos comandos. JMESPath é uma linguagem de consulta para JSON, dando-lhe a capacidade de selecionar e modificar dados da saí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 JMESPath que são úteis para consulta 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 comandos da CLI do Azure. As consultas são executadas no lado do cliente no objeto JSON retornado do comando da CLI do Azure antes de qualquer formatação de exibição.

Os caracteres de escape necessários nas consultas diferem para ambientes diferentes. É recomendável executar consultas no Azure Cloud Shell ou 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 de resultados da CLI

Os resultados do comando CLI são primeiro tratados 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
}

Comandos que podem retornar mais de um objeto retornam uma matriz e comandos que sempre retornam apenas um único objeto retornam um dicionário.

Obter propriedades em um dicionário

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

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

O comando gera um dicionário. Alguns conteúdos foram omitidos.

{
  "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 públicas SSH autorizadas a se conectar à 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 de consulta diferenciam maiúsculas de minúsculas. Por exemplo, alterar 'osProfile' para 'OsProfile' na consulta anterior não retorna os resultados corretos.

Obter vários valores

Para obter mais de uma propriedade, coloque expressões separadas por vírgulas entre colchetes [ ] (uma lista de seleção múltipla). O comando a seguir obtém o nome da VM, o usuário admin 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á chaves associadas aos resultados. Para obter um dicionário em vez de uma matriz, consulte a próxima seção.

Renomear propriedades em uma consulta

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

Nota

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

O nivelamento de uma matriz é feito com o [] operador JMESPath. Todas as expressões após o [] operador são aplicadas a cada elemento na matriz atual. Se [] aparecer no início da consulta, ele nivela o resultado do comando CLI. Os resultados do az vm list podem ser inspecionados com este recurso. A consulta a seguir obtém o nome, o SO e o nome do administrador para 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 nível superior retornado pelo comando. Na última seção, a expressão osProfile.linuxConfiguration.ssh.publicKeys[0].keyData foi usada para obter a chave pública SSH para entrar. Para obter cada chave pública SSH, a expressão poderia ser escrita como osProfile.linuxConfiguration.ssh.publicKeys[].keyData. Esta expressão de consulta nivela a osProfile.linuxConfiguration.ssh.publicKeys matriz e, em seguida, executa a keyData expressão 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 booleanas

A outra operação usada para obter dados de uma matriz é a filtragem. A filtragem é feita com o [?...] operador JMESPath. Este operador toma um predicado como seu conteúdo. Um predicado é qualquer instrução (incluindo propriedades booleanas) que pode ser avaliada para ou truefalse. Expressões em que o predicado é avaliado são true incluídas na saída.

A primeira consulta demonstra como listar os nomes de todas as assinaturas do Azure conectadas à sua conta cuja isDefault propriedade é verdadeira. A segunda e terceira consultas mostram duas maneiras diferentes de listar todas as assinaturas cuja isDefault propriedade é 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 operadores lógicos. Estes incluem <, <=, >, >=, ==, e !=. JMESPath também suporta lógica e (&&), ou (||), e não (!). As expressões podem ser agrupadas entre parênteses, permitindo expressões de predicados mais complexas. Para obter todos os detalhes sobre predicados e operações lógicas, consulte a especificação JMESPath.

Na última seção, você nivelou uma matriz para obter a lista completa de todas as VMs em um grupo de recursos. Com o uso de filtros, essa saída pode ser restrita apenas a VMs 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 maior ou igual 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 dados.

Importante

Em JMESPath, as cadeias de caracteres são sempre cercadas por 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

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

As expressões são avaliadas antes de chamar a função, de modo que os próprios argumentos podem ser expressões JMESPath. Os exemplos a seguir demonstram esse conceito usando contains(string, substring), que verifica se uma cadeia de caracteres contém uma substring. Este comando localiza todas as VMs que usam armazenamento SSD para seus discos do sistema operacional:

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 tubo

Semelhante a como | é usado na linha de comando, | pode ser usado em 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 encurtar 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"
  }
]

Consulte a especificação JMESPath - Built-in Functions para obter a lista completa de funções.

Manipulando a saída com funções

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

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

Consulte a especificação JMESPath - Built-in Functions para obter a lista completa de funções.

Formatar resultados de consulta

A CLI do Azure usa JSON como seu formato de saída padrão, no entanto, diferentes formatos de saída podem se adequar melhor a uma consulta, dependendo de sua finalidade e resultados. As consultas são sempre executadas na saída primeiro e, em JSON seguida, formatadas.

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

Formato de saída TSV

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

Um caso de uso para tsv formatação são consultas que recuperam um valor de um comando da CLI, como uma ID de recurso do Azure ou um nome de recurso, 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 caracteres " . As aspas não podem ser interpretadas pelo shell se a saída do comando for atribuída diretamente à variável de ambiente. Esse problema pode ser visto no exemplo a seguir 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"

Use tsv a formatação, conforme demonstrado na consulta a seguir, para evitar incluir valores de retorno com informações de tipo:

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, o que facilita a leitura e análise. Nem todos os campos estão incluídos na tabela, pelo que este formato é melhor utilizado como uma visão geral dos dados pesquisável por humanos. Os campos que não estão incluídos na tabela ainda podem ser filtrados como parte de uma consulta.

Nota

Algumas chaves são filtradas e não são impressas na vista de tabela. Estas chaves são id, type e etag. Para ver estes valores, pode alterar o nome da chave numa seleção múltipla de hash.

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

Podemos usar uma consulta anterior para demonstrar esse conceito. A consulta original retornou um objeto JSON contendo o nome, o SO e o nome do administrador para 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 combinados com o --output table formato de saída, os nomes das colunas correspondem displayKey ao valor do hash de seleção múltipla, facilitando a leitura das 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óximos passos

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

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