リソースIDの一括取得とタグ情報の一括出力
ども、みなさんタグ使ってますか?
AzureでのタグはKey:Value形式で設定していきますが、基本的にはリソース名の命名規則に入れたかったけど長すぎて見づらくなるため断念した管理情報なんかをタグ情報に入れることがよくあるケースかと思います。
例えばこんな感じで設定しますよね。
Azure Portalからも設定できますし、1つ1つのリソースに対して確認することも視覚的にもやりやすく実装されています。また、AWSのように特定のバッチ処理を走らせるかどうかの判定フラグようにタグ情報にバッチの最終終了時間などを更新して入れておき、バッチ起動時にそのタグ情報の日時を見てバッチサーバーからバッチ処理を走らせるかどうかを決める、といった運用をされている方もいます。
そんな便利なタグ情報ですが、、、
が、
が、
が、例えば上記のようなタグを付与したリソースが300個以上ある、タグも1つや2つじゃなく5個10個ある、といった場合においては、各リソースにタグがちゃんと付与されているかどうかってどうやって確認しましょうかね?
もちろんサブスクリプションやリソースグループの分け方によって、1か所のリソースグループにそんな大量なリソースがデプロイされているケースも少ないかもしれませんが、Cloud Adption FrameworkやWell-Archited Frameworkなんかでは、開発・検証・本番用でワークロード毎に分けてリソースグループを作成しましょう、というお作法があるので、エンタープライズなお客様において長くAzureをご利用されているケースは、本番用リソースグループ内では普通に大量にリソースがあるのではないかと思います。
また、リソースを作成する際に必ずタグ情報を入れないといけない縛りや、もしタグ情報が付与されていない場合は自動的にタグ情報を付与する、といったAzure Policyの定義(厳密には複数のタグ情報を付与する場合はカスタム定義)があるため、DeployIfNotExistsなどを利用すればモレはなくなるであろう設定はできます。
ご参考:
チュートリアル:タグ ガバナンスを管理する - Azure Policy | Microsoft Learn
ただ、Azure Policyの初期設定(割り当て)の際に、どれぐらいの頻度で既存リソースにタグが継承されていくのだろうか、ちゃんと想定している通りタグ情報が特定のリソースグループ配下のリソースに継承されているだろうか、というテスト目的も含めた確認を行いたい場合、200も300もリソースがあるとAzure Portalで目検チェックするにはさすがにシンドイのが実情でしょう。
ということで、リソースグループからリソースを特定し、そのリソースについているタグ情報だけを出力させたい、といったことやってみました。(やっと本題のはじまりw)
まず、Azure Portalにログインし、利用しているサブスクリプションを確認してリソースグループの一覧を取得するためCloudShellを起動しましょう。(bash)
●リソースグループ名一覧の取得
az group list | jq -r ..name
※jqコマンドはCloudShellのbashだとビルトインされているはず。
サンプル出力結果
akira [ ~ ]$ az group list | jq -r ..name
Rg-Dev-Hub-Poc-001
Rg-Prod-Hub-Poc-001
Rg-Stag-Hub-Poc-001
Rg-Dev-Spoke-Poc-001
Rg-Prod-Spoke-Poc-001
Rg-Stag-Spoke-Poc-001
Rg-Dev-Workspace-Poc-001
Rg-Prod-Workspace-Poc-001
Rg-Stag-Workspace-Poc-001
NetworkWatcherRG
cloud-shell-storage-southeastasia
Default-ActivityLogAlerts
akira [ ~ ]$
とりあえずこれで自分が利用しているサブスクリプションで利用されているリソースグループ名の一覧は取得できました。
次に、そのリソースグループ内で利用されているリソース名の一覧を取りに行きます。
●特定のリソースグループ名に対して、その中に存在しているリソースのリソースIDのみ一覧で取得
az resource list --resource-group Rg-Dev-Spoke-Poc-001 | jq -r ..id
サンプル出力結果(サブスクリプションIDだけマスクしてます)
akira [ ~ ]$ az resource list --resource-group Rg-Dev-Spoke-Poc-001 | jq -r ..id
/subscriptions/サブスクリプションID/resourceGroups/RG-DEV-SPOKE-POC-001/providers/Microsoft.Compute/disks/Vm-Dev-Spoke-Poc-001_OsDisk_1_ef5e0627bee342eb8febcd9b79ace92c
/subscriptions/サブスクリプションID/resourceGroups/RG-DEV-SPOKE-POC-001/providers/Microsoft.Compute/disks/Vm-Dev-Spoke-Poc-002_OsDisk_1_08915eedb40f4aaf98ecc70db011df1a
/subscriptions/サブスクリプションID/resourceGroups/Rg-Dev-Spoke-Poc-001/providers/Microsoft.Compute/virtualMachines/Vm-Dev-Spoke-Poc-001
・・
以下省略
akira [ ~ ]$
ここまで来てようやくリソースIDに対してタグ情報を出力することができます。
●リソースIDからタグ情報のみ出力
az tag list --resource-id ${リソースID} | jq .properties.tags
サンプル出力結果
akira [ ~ ]$ az tag list --resource-id /subscriptions/サブスクリプションID/resourceGroups/RG-DEV-SPOKE-POC-001/providers/Microsoft.Compute/disks/Vm-Dev-Spoke-Poc-001_OsDisk_1_ef5e0627bee342eb8febcd9b79ace92c | jq .properties.tags
{
"CostCenterNumber": "10181378",
"date": "2022/12/09",
"division": "Cloud Solution Architect Division1",
"location": "japaneast",
"owner": "akkoike"
}
akira [ ~ ]$
というわけで、これをシェルスクリプトで再帰的に処理するように落とし込むと、こんな感じでしょうかね。
#!/bin/sh
for RG in `az group list | jq -r ..name`
do
echo ${RG}
for RESOURCE_ID in `az resource list --resource-group ${RG} | jq -r ..id`
do
echo ${RESOURCE_ID}
if [ "${RESOURCE_ID}" != "" ]
then
az tag list --resource-id ${RESOURCE_ID} | jq .properties.tags
fi
done
done
実行結果の出力サンプル
Rg-Stag-Hub-Poc-001
Rg-Dev-Spoke-Poc-001
/subscriptions/サブスクリプションID/resourceGroups/RG-DEV-SPOKE-POC-001/providers/Microsoft.Compute/disks/Vm-Dev-Spoke-Poc-001_OsDisk_1_ef5e0627bee342eb8febcd9b79ace92c
{
"CostCenterNumber": "10181378",
"date": "2022/12/09",
"division": "Cloud Solution Architect Division1",
"location": "japaneast",
"owner": "akkoike"
}
/subscriptions/サブスクリプションID/resourceGroups/RG-DEV-SPOKE-POC-001/providers/Microsoft.Compute/disks/Vm-Dev-Spoke-Poc-002_OsDisk_1_08915eedb40f4aaf98ecc70db011df1a
{
"CostCenterNumber": "10181378",
"date": "2022/12/09",
"division": "Cloud Solution Architect Division1",
"location": "japaneast",
"owner": "akkoike"
}
/subscriptions/サブスクリプションID/resourceGroups/Rg-Dev-Spoke-Poc-001/providers/Microsoft.Compute/virtualMachines/Vm-Dev-Spoke-Poc-001
{
"CostCenterNumber": "10181378",
"date": "2022/12/09",
"division": "Cloud Solution Architect Division1",
"location": "japaneast",
"owner": "akkoike"
}
・・
以下省略
まとめ。
ということで特定のリソースグループ内にあるリソース全てのリソースIDを取ることもでき、リソースIDが取れたのでタグ情報を出す、ということができることがわかったかと思います。
ちなみに、
いやいやそんな面倒なことしなくてもARM templateのExport機能使い、"id":の箇所にあるリソースIDだけを引っ張ってこればよくね?と思う方もいると思いますが、こっちのほうがすげーめんどいです。なぜならconcat関数による文字列結合を使った記載になっているため、例えexport時に「--skip-resource-name-params」を引数に入れてparametersの値を文字列出力したとしても、リソースIDの途中で文字列がぶった切れており、concat関数の文法で使うカッコやカンマなどをくりぬいてスラッシュに置き換える、とかとかクソめんどくさいことをしないといけないからですw
今回はいじょーですが、参考となるサイトを張り付けておきますね。
Azure CLI でテンプレートをエクスポートする - Azure Resource Manager | Microsoft Learn
※他にもっと楽ちんで良いやり方があれば教えてくださいww