JMESPath クエリを使用して Azure CLI コマンドの出力に対してクエリを実行する方法

Azure CLI では、--query パラメーターを使用して、コマンドの結果に対して JMESPath クエリを実行します。 JMESPath は、CLI の出力からデータを選択して変更できるようにする、JSON 用のクエリ言語です。

--query パラメーターは、Azure CLI のすべてのコマンドでサポートされています。 この記事では、JMESPath の機能の使用方法とクエリの例について扱います。 [概念] タブでは、クエリの実行に役立つ JMESPath の概念について説明します。[例] タブでは、JMESPath のクエリ例を示します。

Azure CLI では、クエリを使用して、Azure CLI コマンドの出力を選択および変更します。 クエリは、表示の書式設定前に、Azure CLI コマンドの返された JSON オブジェクトのクライアント側で実行されます。

クエリに必要なエスケープ文字は、環境によって異なります。 これらのシェルではエスケープ文字が少なくて済むため、Azure CloudShell または cmd でクエリを実行することをお勧めします。 クエリの例の構文が正しいことを確認するには、使用しているシェルのタブを選択します。

CLI の結果である辞書とリスト

JSON 以外の出力形式を使用している場合でも、CLI コマンドの結果は、クエリのためにまず JSON として扱われます。 CLI の結果は、JSON 配列または JSON 辞書です。 配列はインデックスを作成できるオブジェクトのシーケンスであり、辞書はキーを使用してアクセスされる順序指定されていないオブジェクトです。

以下は配列の例です。

[ 
  1,
  2,
  3
]

以下は辞書の例です。

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

複数のオブジェクトを返すことが "できる" コマンドは配列を返し、"常に" 単一オブジェクト "のみ" を返すコマンドは辞書を返します。

辞書のプロパティを取得する

結果として辞書を使用すると、キーだけで最上位からプロパティにアクセスできます。 . (部分式) 文字は、入れ子になった辞書のプロパティにアクセスする際に使用します。 クエリを導入する前に、az vm show コマンドの未変更の出力を見てみましょう。

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

このコマンドは辞書を出力します。 一部の内容は省略されています。

{
  "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
  },
  ....
}

次のコマンドでは、クエリを追加して、VM への接続を許可された SSH 公開キーを取得します。

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"
  }
]

クエリ文字列では大文字と小文字が区別されることに注意してください。 たとえば、上記のクエリで 'osProfile' を 'OsProfile' に変更すると、正しい結果が返されません。

複数の値を取得する

複数のプロパティを取得するには、式をコンマで区切って角かっこ [ ] (複数選択リスト) で囲みます。 次のコマンドは、VM 名、管理者ユーザー、SSH キーをすべて一度に取得します。

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"
]

これらの値は、クエリで指定された順序で結果の配列に表示されます。 結果は配列であるため、結果に関連付けられたキーはありません。 配列ではなく辞書を取得するには、以下のセクションを参照してください。

クエリでプロパティの名前を変更する

複数の値のクエリを実行するときに、配列ではなく、辞書を取得するには、{ } (複数選択ハッシュ) 演算子を使用します。 複数選択ハッシュの形式は、{displayName:JMESPathExpression, ...} です。 displayName は出力に表示される文字列であり、JMESPathExpression は評価する JMESPath 式です。 複数選択リストをハッシュに変更して、前のセクションの例を変更します。

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"
}

配列内のプロパティを取得する

配列には独自のプロパティはありませんが、インデックスを作成できます。 この機能は、前の例の式 publicKeys[0] で示されています。これは、publicKeys 配列の最初の要素を取得します。 CLI の出力が順序付けられているという保証はないため、順序が確かである場合や取得する要素を気にかけない場合を除き、インデックスを使用しないようにしてください。 配列内の要素のプロパティにアクセスするには、フラット化フィルター処理 の 2 つの操作のいずれかを実行します。 このセクションでは、配列をフラット化する方法について説明します。

配列のフラット化は、[] JMESPath 演算子を使用して実行します。 [] 演算子の後のすべての式が、現在の配列内の各要素に適用されます。 [] がクエリの先頭にある場合、CLI コマンドの結果がフラット化されます。 この機能を使用して、az vm list の結果を検査できます。 次のクエリは、リソース グループ内の各 VM の名前、OS、管理者名を取得します。

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"
  }
]

コマンドから返される最上位の結果だけでなく、配列もフラット化できます。 前のセクションでは、式 osProfile.linuxConfiguration.ssh.publicKeys[0].keyData を使用して、サインイン用の SSH 公開キーを取得しました。 "すべての" SSH 公開キーを取得するには、この式を osProfile.linuxConfiguration.ssh.publicKeys[].keyData と記述します。 このクエリ式では、osProfile.linuxConfiguration.ssh.publicKeys 配列をフラット化し、各要素に対して keyData 式を実行します。

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"
  ]
}

ブール式を使用して配列をフィルター処理する

配列からデータを取得するときに使用するもう 1 つの操作は "フィルター処理" です。 フィルター処理は、[?...] JMESPath 演算子を使用して実行します。 この演算子は、その内容として述語を受け取ります。 述語とは、ブール値のプロパティを含めた、true または false に評価できるステートメントです。 述語が true に評価された式が出力に含まれます。

最初のクエリは、isDefault プロパティが true のアカウントに接続されているすべての Azure サブスクリプションの名前の表示方法を示します。 2 番目と 3 番目のクエリは、isDefault プロパティが false のすべてのサブスクリプションを表示する 2 種類の方法を示します。

# 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 では、標準の比較演算子と論理演算子が提供されています。 これらには、<<=>>===!= が含まれます。 JMESPath では、論理 AND (&&)、論理 OR (||)、論理 NOT (!) もサポートされています。 式をかっこ内にグループ化できるので、より複雑な述語式を使用できます。 述語と論理演算の詳細については、JMESPath の仕様をご覧ください。

前のセクションでは、配列をフラット化して、リソース グループ内のすべての VM の完全なリストを取得しました。 フィルターを使用すると、この出力を Linux VM だけに制限できます。

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

OS ディスク サイズなどの数値をフィルター処理することもできます。 次の例は、VM のリストをフィルター処理して、ディスク サイズが 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

大きな配列では、データを選択する前にフィルターを適用する方が速い場合があります。

重要

JMESPath では、文字列は常に単一引用符 (') またはエスケープ文字 (`) で囲みます。 フィルター述語の文字列の一部として二重引用符を使用すると、空の出力が返されます。

JMESPath の関数

JMESPath には、より複雑なクエリやクエリ出力の変更を可能にする関数も組み込まれています。 このセクションでは、JMESPath 関数を使用してクエリを作成することに焦点を当て、「関数を使用した出力の操作」のセクションでは、関数を使用して出力を変更する方法を示します。

関数を呼び出す前に式が評価されるので、引数自体を JMESPath 式にすることができます。 次の例では、これを示すために文字列に substring が含まれているかどうかを確認する contains(string, substring) を使用しています。 このコマンドは、OS ディスクに SSD ストレージを使用するすべての VM を検出します。

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"
  }
]

パイプ式

コマンド ラインで | を使用する場合と同様に、| を JMESPath クエリで使用して、中間クエリ結果に式を適用することができます。 また、複雑なクエリを単純な部分式に分割するために | を使用することもできます。 前のセクションのクエリを短縮するには、| を使用してデータをフラット化して選択した後にフィルターを適用します。

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"
  }
]

関数の全一覧については、JMESPath の仕様の組み込み関数に関するセクションをご覧ください。

関数を使用した出力の操作

JMESPath の関数には別の目的もあります。それは、クエリの結果を操作することです。 ブール値以外の値を返す関数では、式の結果が変更されます。 たとえば、sort_by(array, &sort_expression) を使用して、データをプロパティ値で並べ替えることができます。 JMESPath では、関数の一部として後で評価する必要がある式に、特殊演算子の & を使用します。 次の例は、VM のリストを OS ディスク サイズで並べ替える方法を示しています。

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

関数の全一覧については、JMESPath の仕様の組み込み関数に関するセクションをご覧ください。

クエリの結果の書式設定

Azure CLI では既定の出力形式として JSON が使用されますが、目的と結果によっては、異なる出力形式がクエリに適している場合があります。 クエリは常に最初に JSON 出力で実行され、次に書式設定されます。

このセクションでは、tsvtable の書式設定と、各書式のユース ケースについて説明します。 その他の出力形式の詳細については、「Azure CLI コマンドの出力形式」を参照してください。

TSV 出力形式

tsv 出力形式では、追加の書式設定、キー、またはその他の記号なしで、タブと改行で区切られた値が返されます。 これは、出力が別のコマンドによって使用される場合に役立ちます。

tsv の書式設定のユース ケースの 1 つが、CLI コマンドから Azure リソース ID やリソース名などの値を取得し、その値をローカル環境変数に格納するクエリです。 既定では、結果は JSON 形式で返されます。 これは、" 文字で囲まれた JSON 文字列を処理する場合に問題になる可能性があります。 コマンド出力が環境変数に直接割り当てられている場合、シェルによって引用符が解釈 されない 場合があります。 これは、クエリ結果が環境変数に割り当てられる次の例で確認できます。

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

戻り値が型情報で囲まれるのを防ぐには、次のクエリで示すように tsv 書式設定を使用します。

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

テーブル出力形式

table 形式では出力が ASCII テーブルとして生成されるため、読み取りやスキャンが容易になります。 この形式では一部のフィールドがテーブルに含まれないため、人の目で検索できるデータ概要に最適です。 テーブルに含まれないフィールドも、クエリの一部として引き続きフィルター処理できます。

注意

特定のキーはフィルター処理され、テーブル ビューには出力されません。 これらのキーは、idtype、およびetag です。 これらの値を表示するには、複数選択ハッシュのキー名を変更します。

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

前のクエリを使用してこれを示すことができます。 元のクエリでは、リソース グループ内の各 VM の名前、OS、管理者名を含む JSON オブジェクトが返されました。

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"
  }
]

--output table 出力形式と組み合わせた場合、列名は複数選択ハッシュの displayKey 値と一致するため、情報を見つけやすくなります。

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

次のステップ

JMESPath クエリの詳細については、「JMESPath Tutorial」 (JMESPath のチュートリアル) を参照してください。

この記事で説明している他の Azure CLI の概念の詳細については、次を参照してください。