こんにちは🎄
この記事は、Microsoft Azure Tech Advent Calendar 2022 20日目の記事です。
この記事では、Azure リソースの管理に便利な Azure Resource Graph について利用シーンを踏まえ紹介してみます。
Azure Resource Graph とは
Azure Resource Graphは、Azure AD テナント全体に対して、
様々リソースに対し、Kusto Query Language (KQL) で探索できるサービスで、
2019 年に一般提供されました。
ただし、KQL の記法が全て使えるわけでない状況 (変数を定義する let は未対応) です。
検索方法としては、Azure Resource Graph エクスプローラや、
各種 SDK 、Azure CLI / Azure PowerShell が利用できるようになっています。
また、利用に際して料金はかかりませんが、
決められた時間に使用回数の制限 (クォータ) が設けられており、5秒毎、最大15回のクエリの送信が可能です。
このクォータ情報は、クエリ送信した際のレスポンスヘッダーに含まれ、
例えば、 Azure CLI を利用される場合には、"--debug" オプションにて確認可能です。
$ az graph query -q 'resourcechanges | project properties.changeAttributes.timestamp, properties.changeType, properties.targetResourceId, properties.targetResourceType, properties.changes | limit 5' --debug
…
cli.azure.cli.core.sdk.policies: Response status: 200
cli.azure.cli.core.sdk.policies: Response headers:
…
cli.azure.cli.core.sdk.policies: 'x-ms-ratelimit-remaining-tenant-resource-requests': '14'
cli.azure.cli.core.sdk.policies: 'x-ms-user-quota-remaining': '14'
cli.azure.cli.core.sdk.policies: 'x-ms-user-quota-resets-after': '00:00:05'
cli.azure.cli.core.sdk.policies: 'x-ms-resource-graph-request-duration': '0:00:00:01.2570864'
….
出典; スロットルされた要求に関するガイダンス - Azure Resource Graph | Microsoft Learn
以下、IaaS に偏った内容となっておりますが、
代表的な3つの利用シーンについて紹介できればと思います。
- リソースを探索する
- リソースの変更を確認する
- 正常性を確認する
また、以降のクエリには、サブスクリプションを絞りこむために、
| where subscriptionId == "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
と指定しているので、
試してみる際には、ご自身のサブスクリプション ID にて置き換えてください。
リソースを探索する
利用シーンとしては、無用な課金を抑えたいという場合があるかと思います。
Azure VM であれば、使われていない (どの仮想マシンにもアタッチされていない) ディスクを以下のクエリにて確認できます。
Resources
| where type has "microsoft.compute/disks"
| where subscriptionId == "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
| extend diskState = tostring(properties.diskState), allProperties = pack_all()
| where diskState == 'Unattached'
| project id, diskState, resourceGroup, location, allProperties
また、パブリック IP アドレスもついつい消し忘れてしまいがちです。そのようなパブリック IP アドレスを以下のクエリで探してみます。
むむ... 22 件。まさにコスト掛かっているところが分かりました。
Resources
| where type == "microsoft.network/publicipaddresses"
| where subscriptionId == "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
| extend allProperties = pack_all()
| where properties.ipConfiguration == "" and properties.natGateway == ""
| project id, name, resourceGroup, location, sku.name, allProperties
さらに管理ディスクの種別を調べ、検証用途など性能をあまり必要としない場合に、
SKU を変えるということも検討されるかと思います。
まずは、今現時点の管理ディスクでどの程度の割合なのか、以下のクエリで把握してみます。
(Premium SSD v2 ディスクを考慮していないので、これは別途要検討..)
Resources
| where type =~ 'Microsoft.Compute/disks'
| where subscriptionId == "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
| extend diskSku=case(sku.name =~ "Standard_LRS", "Standard HDD", sku.name =~ "StandardSSD_LRS", "Standard SSD", sku.name =~ "Premium_LRS", "Premium SSD", sku.name), allProperties = pack_all()
| project diskSku, sku.name, sku.tier, allProperties
| summarize count() by diskSku
既定でテーブル表示のところ、[グラフ] を押して見るともう少し視覚的に分かりやすい表示も可能です。
同様に、仮想マシンサイズについて見てみましょう。
Resources
| where type == 'microsoft.compute/virtualmachines'
| where subscriptionId == "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
| summarize count() by VMSize = tostring(properties.hardwareProfile.vmSize)
あとは、仮想マシンの電源状態によっては、コンピュートリソース分の課金が発生するので、
どの程度の仮想マシンが停止 (割り当て解除)されているか、確認してみます。
Resources
| where type == 'microsoft.compute/virtualmachines'
| where subscriptionId == "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
| summarize count() by PowerState = tostring(properties.extended.instanceView.powerState.code)
出典; 状態と課金状態 - Azure Virtual Machines | Microsoft Learn
クエリの結果は、ダッシュボードにピン止めすることができるので、
必要に応じて、共有しておくと便利です。
リソースの変更を確認する
次に Azure リソースの変更履歴を確認してみます。
Resourcechanges テーブルにて、Azure リソースに対して実行された最大7日前までのCRUD操作が取得できます。
例; 特定の日時 (以下は、2022-12-17 00:30 UTC) 以降の変更操作を取得
resourcechanges
| where subscriptionId == 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
| extend changeTime = todatetime(properties.changeAttributes.timestamp), targetResourceId = tostring(properties.targetResourceId),
changeType = tostring(properties.changeType), correlationId = properties.changeAttributes.correlationId,
changedProperties = properties.changes, changeCount = properties.changeAttributes.changesCount
| where changeTime > datetime("2022-12-17T00:30:00.000Z")
| order by changeTime desc
| project changeTime, targetResourceId, changeType, correlationId, changeCount, changedProperties
例; Azure リソースの削除操作を確認
resourcechanges
| where subscriptionId == 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
| extend changeTime = todatetime(properties.changeAttributes.timestamp), targetResourceId = tostring(properties.targetResourceId),
changeType = tostring(properties.changeType), correlationId = properties.changeAttributes.correlationId, allProperties = pack_all()
| where changeType == "Delete"
| order by changeTime desc
| project changeTime, resourceGroup, targetResourceId, changeType, correlationId, allProperties
ただ誰が操作されたか確認されたい場合では、操作者 (caller) のプロパティが含まれていないので、
アクティビティログとの突合せが必要になります (以下の例では、日時とcorrelation ID で対象アクティビティログを確認しています)。
出典; Azure アクティビティ ログのイベント スキーマ - Azure Monitor | Microsoft Learn
正常性を確認する
Azure では正常について各リソースの正常性と、サービス正常性の2つがあります。
出典; Azure Service Health とは - Azure Service Health | Microsoft Learn
リソース正常性
Azure Resource Graph から確認できるリソース正常性の情報については、
下記にある通り、現時点で仮想マシンのみとなっています。
出典; Project Flash で Azure 仮想マシンの可用性の監視を進化させる | Azure のブログと更新プログラム | Microsoft Azure
現在、Azure Resource Graph の Health Resources テーブルに VM の可用性状態 (使用可能、使用不可、不明) が出力されており、お客様は、大規模データセットを同時にふるい分けるための複雑な Kusto Query Language (KQL) クエリを実行することができます。この機能は、VM 可用性の過去の変化を追跡したり、カスタム ダッシュボードを構築したり、複数のテーブルにまたがる多数のリソース プロパティを詳細に調査したりするのに便利です。
また、実行してみると直近1日のリソース正常性に変化があった場合のみレコードが取得できる状況になります。
HealthResources
| where type =~ 'microsoft.resourcehealth/availabilitystatuses'
| where subscriptionId == 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
| where tostring(properties.targetResourceType) =~ 'microsoft.compute/virtualmachines'
| extend allProperties = pack_all()
| project targetResourceId = tolower(tostring(properties.targetResourceId)), previousAvailabilityState = properties.previousAvailabilityState, currentAvailabilityState = properties.availabilityState, occurredTimeUTC = properties.occurredTime, allProperties
| order by ['targetResourceId'] asc
また、'microsoft.resourcehealth/resourceannotations' の情報と併せると、リソース正常性の変化の要因 (ユーザー操作 / Azure 基盤起因) が分かるので、その結果と併せて確認してみます。
HealthResources
| where type =~ 'microsoft.resourcehealth/availabilitystatuses'
| where subscriptionId == 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
| project targetResourceId = tolower(tostring(properties.targetResourceId)), previousAvailabilityState = properties.previousAvailabilityState, currentAvailabilityState = properties.availabilityState, occurredTimeUTC = properties.occurredTime
| join kind=leftouter (
HealthResources
| where type =~ 'microsoft.resourcehealth/resourceannotations'
| where subscriptionId == 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
| project Id = tolower(tostring(properties.targetResourceId)), properties.summary, properties.context, properties.reason)
on $left.targetResourceId == $right.Id
| project-away Id
サービス正常性
サービス正常性について履歴も含め取得することが可能です。
例えば、サービスの問題 (eventType が ServiceIssue) の場合は、以下のように取得できます。
ServiceHealthResources
| where type =~ 'Microsoft.ResourceHealth/events'
| where subscriptionId == 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
| extend eventType = tostring(properties.EventType), status = properties.Status, description = properties.Title, trackingId = properties.TrackingId, summary = properties.Summary, priority = properties.Priority, impactStartTime = todatetime(tolong(properties.ImpactStartTime)), impactMitigationTime = todatetime(tolong(properties.ImpactMitigationTime)), allProperties = pack_all()
| where eventType == "ServiceIssue"
| project trackingId, eventType, status, priority, impactStartTime, impactMitigationTime, summary, allProperties
計画メンテナンス (eventType が PlannedMaintenance) の場合のクエリはこちらで取得できます。
ServiceHealthResources
| where type =~ 'Microsoft.ResourceHealth/events'
| where subscriptionId == 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
| extend eventType = tostring(properties.EventType), status = properties.Status, description = properties.Title, trackingId = properties.TrackingId, summary = properties.Summary, priority = properties.Priority, impactStartTime = todatetime(tolong(properties.ImpactStartTime)), impactMitigationTime = todatetime(tolong(properties.ImpactMitigationTime)), allProperties = pack_all()
| where eventType == "PlannedMaintenance"
| project trackingId, eventType, status, priority, impactStartTime, impactMitigationTime, summary, allProperties
紹介できるレコードが無かったのですが、正常性やセキュリティに関する勧告も取得できるかと思います。
出典; Service Health クラシック エクスペリエンスの概要 - Azure Service Health | Microsoft Learn
今後
仮想マシンの可用性監視を強化していこうというProject Flash というプロジェクトが進められており、その1つのサービスとして ARG は位置づけられています。
この記事で興味を持ってもらえれば幸いです。
明日は同じチームの @atakada がAKSのメモリ周りのトラブルシューティングについてご紹介されるみたいです。
お楽しみに🎁