はじめに
今回は、Azure のリソース検索に便利な Resource Graph のクエリについてです。
Resource Graph は特定のリソースを検出するうえで非常に便利ですが、
KQL を扱う必要があり、最初のうちはとっつきにくいところがあります。
ということで、コピペでそのまま使えるものをいくつかサンプルとして挙げてみます。
IaaS 系中心ですが、そのまま使用する、ちょっと手を加える、書き方を知るなど、何かしらの参考になれば幸いです。
目次
KQL リファレンス
関数の説明までは載せていないので、KQL のリファレンスを貼っておきます。
以下を参照してもらったり、コメント(先頭にダブルスラッシュでコメント化) したり、値を変えたりして。
docs.microsoft.com
もしくはこっちを参照すれば大体載っていると思います。
※左の縦メニューの中に型とか演算子とかいろいろ
docs.microsoft.com
SQL がわかる方はここを見ると KQL の理解が早いかもしれません。
docs.microsoft.com
Resource Graph クエリ サンプル
Compute 系
OS 種類別の VM 台数
OS 別の集計
Resources
| where type =~ 'Microsoft.Compute/virtualMachines'
| summarize count() by tostring(properties.storageProfile.osDisk.osType)
実行結果
ResourceGraph1
VM の情報と、使用している Dedicated Host 名
Resources
| where type =~ "Microsoft.Compute/virtualmachines"
| project name, resourceGroup, subscriptionId, dedicatedHost=split(properties.host.id,"/")[8]
実行結果
サイズ別 VM 台数を、降順で表示
サイズ別の集計
resources
| where type =~ "Microsoft.Compute/VirtualMachines"
| summarize count() by tostring(properties.hardwareProfile.vmSize)
| sort by count_ desc
実行結果
Storage 系
古いスナップショットの上位 10 個
使われず置いたままのスナップショット検索に。
Resources
| where type =~ "Microsoft.Compute/snapshots"
| project name, resourceGroup,properties.timeCreated
| sort by tostring(properties_timeCreated) asc
| take 10
実行結果
ResourceGraph2
未接続の管理ディスク
使われず置いたままの管理ディスク検索に。
Resources
| where type =~ "Microsoft.Compute/disks"
| where properties.diskState == "Unattached"
実行結果
ResourceGraph3
"Blob パブリック アクセスを許可" 設定が有効のストレージ アカウント
ストレージアカウント側の "パブリック アクセス許可" が有効なだけで、
実際にパブリック公開しているかどうかはコンテナー側の設定によります。
Resources
| where type =~ "Microsoft.Storage/storageaccounts"
| where properties.allowBlobPublicAccess == true
実行結果
ResourceGraph5
各ストレージ アカウントの "安全な転送が必要" と "Blob パブリックアクセスを許可"、"TLS の最小バージョン" の設定値
原因がわかりませんが、稀に設定値が空欄となり表示されないリソースがあります。
※作成時期が古いものだとなるかも?
Resources
| where type =~ "Microsoft.Storage/storageaccounts"
| project name, resourceGroup, properties.supportsHttpsTrafficOnly, properties.allowBlobPublicAccess, properties.minimumTlsVersion
実行結果
ResourceGraph6
Network 系
未接続のパブリック IP アドレス
使われず置いたままのパブリック IP アドレス検索に。
Resources
| where type =~ "Microsoft.Network/publicipaddresses"
| where isnull(properties.ipConfiguration)
実行結果
ResourceGraph4
Small もしくはインスタンスが 1 台以下の Application Gateway
Small 、もしくはインスタンスが 1 台以下の場合、Application Gateway の SLA 対象外です。
Resources
| where type =~ "Microsoft.Network/applicationgateways"
| where properties.sku.name == "Standard_Small" or properties.sku.capacity <= 1
| project name, properties.sku.name, properties.sku.capacity
| sort by tostring(properties_sku_name), tostring(properties_sku_capacity) asc
実行結果
ResourceGraph7
"高速ネットワーク" が無効なネットワーク インターフェイス
これだと NIC の設定値を見ているだけなので、どの VM かがわかりづらいです。
次に VM テーブルとの join 版を掲載しています。
Resources
| where type =~ "Microsoft.Network/NetworkInterfaces"
| where properties.enableAcceleratedNetworking == "false"
| project name, subscriptionId, properties.enableAcceleratedNetworking
実行結果
ResourceGraph8
各 VM のネットワーク インターフェイス名と "高速ネットワーク" の設定値 (join 版)
VM のテーブルと NIC のテーブルを join することで、どの VM のどの NIC かがわかりやすくなります。
※複数 NIC の場合は考慮していません。
resources
| where type =~ "Microsoft.Compute/virtualmachines"
| project name, resourceGroup, size=tostring(properties.hardwareProfile.vmSize), subscriptionId, nic=tostring(split(properties.networkProfile.networkInterfaces[0].id, "/")[8])
| join kind = leftouter ( resources| where type =~ "Microsoft.Network/NetworkInterfaces") on $left.nic == $right.name
| project vm=name,subscriptionId, resourceGroup, nic, size, enableAcceleratedNetworking=properties.enableAcceleratedNetworking
実行結果
ResourceGraph9
Basic ロードバランサー
リタイアする Basic ロードバランサーの発見用に
Resources
| where type =~ "Microsoft.Network/Loadbalancers"
| where sku.name == "Basic"
実行結果
バックエンド プールが空の Application Gateway
使われず置いたままの Application Gateway 検索に。
resources
| where type =~ "Microsoft.Network/applicationGateways"
| where properties.backendAddressPools.properties.backendAddresses == ""
実行結果
Basic SKU のパブリック IP アドレス、ロードバランサー
リタイアに向けての検出用
resources
| where type == "microsoft.network/publicipaddresses" or type == "microsoft.network/loadbalancers"
| where sku.name == "Basic"
実行結果
ネットワーク インターフェースごとの、DNS 設定
個別設定の把握用
resources
| where type =~ "Microsoft.Network/networkinterfaces"
| project id, name, resourceGroup, DNS=properties.dnsSettings.dnsServers
実行結果
送信元を Any で許可している受信規則を持つ NSG とそのルール情報
広く許可し過ぎなルールを発見したいときに
resources
| where type =~ "Microsoft.Network/networksecuritygroups"
| mv-expand rule = properties.securityRules
| where tostring(rule.properties.sourceAddressPrefix) == "*" and tostring(rule.properties.access) == "Allow" and tostring(rule.properties.direction) == "Inbound"
| project id, name, resourceGroup, subscriptionId, ruleName = rule.name, rule
実行結果
Azure FW とそのプライベート IP アドレス
Azure FW 毎にプライベート IP アドレスを確認するのが面倒なときに
resources
| where type =~ "Microsoft.Network/azurefirewalls"
| mv-expand ipCnof = properties.ipConfigurations
| extend fwIp = ipCnof.properties.privateIPAddress
| project id, name, resourceGroup, fwIp
実行結果
Application Gateway と、そのバックエンドに指定されている IP アドレス
どんな IP が指定されていたっけ?というのをまとめて確認したいときに
resources
| where type =~ "Microsoft.Network/applicationgateways"
| where location == "japaneast"
| mv-expand backendPool = properties.backendAddressPools
| mv-expand backendAddresses = backendPool.properties.backendAddresses
| extend backendAddress = tostring(backendAddresses.ipAddress)
| project id, name, resourceGroup, backendAddress
実行結果
特定のサービス タグを宛先 or 送信先にしている NSG ルール
このサービス タグどこで使ってたっけ?というときに for NSG
NSG の properties 内で rule 配列に格納されているルールを、mv-expand で展開するのがポイント
resources
| where type =~ "Microsoft.Network/NetworkSecurityGroups"
| mv-expand rule = properties.securityRules
| extend source = rule.properties.sourceAddressPrefix
| extend destination = rule.properties.destinationAddressPrefix
| extend ruleName = rule.name
| where source == "AzureUpdateDelivery" or destination == "AzureUpdateDelivery"
| project id, name, location, resourceGroup, subscriptionId, ruleName, source, destination
実行結果
特定のサービス タグを対象にしているルート テーブルのルール
このサービス タグどこで使ってたっけ?というときに for ルート テーブル
これも mv-expand での展開がポイント
resources
| where type =~ "Microsoft.Network/routetables"
| mv-expand route = properties.routes
| extend routeName = route.name
| extend addressPrefix = route.properties.addressPrefix
| where addressPrefix == "AzureUpdateDelivery"
| project id, name, location, resourceGroup, subscriptionId, routeName, addressPrefix
実行結果
特定のサービス タグを対象にしている Azure Firewall のネットワーク ルール
このサービス タグどこで使ってたっけ?というときに for Azure Firewall
Azure Firewall でサービス タグが使えるのは、ネットワーク ルールのみ
これも mv-expand だが、1 回目で複数のコレクションを展開し、2 回目でコレクション内のルールを展開するのがポイント
resources
| where type =~ "Microsoft.Network/AzureFirewalls"
| mv-expand nwRules = properties.networkRuleCollections
| mv-expand nwRule = nwRules.properties.rules
| extend ruleName = nwRule.name
| extend sourceAddresses = nwRule.sourceAddresses
| extend destinationAddresses = nwRule.destinationAddresses
| where sourceAddresses contains "AzureUpdateDelivery" or destinationAddresses contains "AzureUpdateDelivery"
| project id, name, location, resourceGroup, subscriptionId, ruleName, sourceAddresses, destinationAddresses
実行結果
その他
Notification Id 毎の Azure リソースのメンテナンス情報
maintenanceresources
| extend p = parse_json(properties)
| mvexpand d = p.value
| project notificationId=properties.value[0].notificationId, id=substring(id, 0, indexof(id, "/providers/Microsoft.Maintenance")), resourceGroup, subscriptionId, status=d.status, detail=d
実行結果
メンテナンス対象リソースがないため取れたら追加
メンテナンス対象のリソースとその日時など
メンテナンス対象とその状況取得用
maintenanceresources
| mv-expand properties.value
| project notificationId=properties_value.notificationId, resourceId=properties_value.properties.resourceId ,resourceGroup, location, subscriptionId, Status=properties_value.status, StartTimeUtc=properties_value.startTimeUtc, endTimeUtc=properties_value.endTimeUtc, impactType=properties_value.impactType
| where Status != "Completed"
実行結果
こっちのサポート チームブログを見た方がいろいろ載ってていいかも
jpaztech.github.io
終わりに
今回はサンプル集としての記事でした。
クエリについては習うより慣れろで実際に動かしてみるのが一番かと思いますので、リファレンスを見つつ実際に動かしてみてください。
関数を使いこなせればもっといろいろできて楽しそうなのですが、自分でもまだそこまで扱えておらず join をちょっと試したくらい…
同じような、使ってみたいけどよーわからん、という方の参考になれば嬉しいです。
また、今後新しいクエリを作成できたら、更新していきたいと思います。