-Debug を使って Azure PowerShell の操作がどの ARM の制限（スロットリング）にカウントされるかを調べる

こんにちは、アーキテクトのやまぱんです。
補足コメントや質問、<font color="red">**いいね、拡散**</font>、是非お願いします🥺！
間違ってたら<font color="red">**優しく**</font>教えてください！

Azure PowerShell を使用して Azure リソースを管理する際、リソース操作が Azure Resource Manager (ARM) の制限（スロットリング）に抵触することがあります。Azure のスロットリングは、API の呼び出し回数やリソース使用量の上限に基づき、一定の制限に達した場合に適用され、操作の失敗や待機時間が発生する原因となります。

Azure PowerShell の -Debug パラメータを使用することで、操作が内部でどのように ARM API を呼び出し、制限にカウントされているかを確認できます。本記事では、-Debug を使ってどの ARM 制限にカウントされるかを調べる方法と、スロットリングの調査について記載します。

+ Azure Resource Manager が要求を調整する方法の概要

https://learn.microsoft.com/ja-jp/azure/azure-resource-manager/management/request-limits-and-throttling#storage-throttling

## ARM のスロットリングとは
Azure Resource Manager (ARM) では、特定のリソースプロバイダーに対する API リクエストが多すぎる場合に、自動的にリクエストを制限（スロットリング）する仕組みが存在します。この制限により、リソース操作が一時的に失敗し、以下のようなエラーが返されることがあります。

HTTP 429 - Too Many Requests: リクエストレートが高すぎるために発生するエラー。

このエラーは、Azure Resource Manager のレート制限に抵触したことを意味し、特定の操作がどの制限にカウントされているかを特定することで、より効率的なリソース管理が可能になります。

スロットリングにはテナントレベル、サブスクリプションレベル、リソース(リソースプロバイダー(Microsoft.Compute など))レベルで存在します。
 要求がサブスクリプションとテナントの調整制限内に収まる場合、Resource Manager によって要求はリソース プロバイダーにルーティングされます。 リソース プロバイダーでは、その操作に合わせた調整制限が適用されます。

## `-Debug` を使って ARM 制限にカウントされる操作を調べる方法
-Debug パラメータを使用すると、Azure PowerShell コマンドの内部で実行される HTTP リクエストの詳細を確認できます。これにより、どのリソースプロバイダー（例: Microsoft.Compute、Microsoft.Network、Microsoft.Storage）に対する操作が行われ、どの API 呼び出しが制限（スロットリング）にカウントされているかを特定できます。


### `-Debug` を使ったリクエストとレスポンスの確認手順
Azure PowerShell コマンドの実行時に -Debug パラメータを付与することで、API リクエストとレスポンスの詳細を表示できます。

例: 仮想マシンの状態を確認する操作
以下の例では、特定の仮想マシンの状態を確認する際に -Debug パラメータを付与して、操作がどの ARM API にカウントされるかを確認します。

:::note info
以下の例ではひとつのリクエストのみだが、コマンドによっては複数のリクエストをおくる場合もある
その場合は複数のリクエストとレスポンスが確認できる。
:::

+ コマンド
```PowerShell:PowerShell
Get-AzVM -ResourceGroupName "rg-test" -Name "test-vm" -Debug
```
+ 結果 -抜粋-
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982508/f0ace30a-81d0-97df-050b-2a3cbec1287f.png)


上記のようにリクエスト内容とレスポンス内容が確認できます。
ここで重要なのは以下です。
>* Absolute Uri
API 呼び出しの対象となる Azure Resource Manager (ARM) エンドポイントを示す完全な URL です。
リソースグループ rg-test 内の、リソースプロバイダー Microsoft.Compute の仮想マシン test-vm を操作していることがわかります。

>*  x-ms-ratelimit-remaining-resource
特定のリソースプロバイダー（例: Microsoft.Compute）に対する残りの API 呼び出し回数を示すヘッダーです。
各リソースプロバイダー（例: Microsoft.Compute）に対して、さらに細分化されたレート制限が設定されており、**LowCostGetSubscriptionMaximum** や **LowCostGetResource** といった操作ごとに残りの呼び出し回数が表示されます。
Microsoft.Compute/LowCostGetSubscriptionMaximum;23999: この項目は、Microsoft.Compute プロバイダーに対する「LowCostGetSubscriptionMaximum」操作の残り回数が **23999** 回であることを示しています。Microsoft.Compute/LowCostGetResource;35: これは、「LowCostGetResource」操作（特定のリソースに対する情報取得）に対する残り回数が **35** 回であることを示しています
:::note info
MS Learnで該当する場所はこちらになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982508/9b770d49-0dcb-7371-6fa0-4eda0a496f11.png)

+ Virtual Machines の調整制限
https://learn.microsoft.com/ja-jp/azure/virtual-machines/compute-throttling-limits#throttling-limits-for-virtual-machines
:::

> * x-ms-ratelimit-remaining-subscription-reads: 249
サブスクリプションレベルでの特定のCRP(Microsoft.Computeなど)に対する読み取り操作(GET)の残り回数を示すヘッダーです。
サブスクリプションレベルであと 249 回の読み取り操作が可能であることを意味しています。
:::note info
MS Learnで該当する場所はこちらになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982508/7ee3520f-67c3-cd0f-5d87-9db086caf949.png)
+ Virtual Machines の調整制限
https://learn.microsoft.com/ja-jp/azure/azure-resource-manager/management/request-limits-and-throttling#migrating-to-regional-throttling-and-token-bucket-algorithm
:::


> * x-ms-ratelimit-remaining-subscription-global-reads: 3749
サブスクリプションレベルで全体に対するグローバルリード操作の残り回数を示すヘッダーです。
例では、**サブスクリプション全体**に対して 3749 回のグローバルな読み取り操作（例: 仮想マシン、ストレージアカウント、ネットワークなど、全リソースにまたがる読み取り操作）が可能であることを意味しています。
:::note info
MS Learnで該当する場所はこちらになります。
250×15=3750
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982508/d958c842-042d-1608-3a53-5ba84d8feea0.png)
+ Virtual Machines の調整制限
https://learn.microsoft.com/ja-jp/azure/virtual-machines/compute-throttling-limits#throttling-limits-for-virtual-machines
:::

## まとめ
Azure Resource Manager (ARM) API では、リソース操作に対するレート制限（API 呼び出しの回数制限）が設定されており、上記のヘッダーを使用して現在の残り回数を確認できます。各ヘッダーは、特定の種類のリクエストが制限に近づいているかどうかを確認するのに役立ちます。これにより、スロットリング（制限超過）の発生を防ぐための調整を行うことが可能です。

これらのヘッダーは、API 呼び出し制限に抵触することなく、Azure サブスクリプションやリソースの読み取り操作を最適に実行するための指標として役立ちます。

もし、これらのヘッダーが示す制限を超過した場合は、HTTP ステータスコード 429 Too Many Requests が返され、API 呼び出しが拒否されるため、十分な間隔を開けてリトライするか、スクリプトの実行頻度を調整(ランダム秒待機するとか)することが必要です。
この 429 エラーは Retry-After ヘッダーとともに返され、指定された時間（例: 数秒～数分）後に再試行するように指示されます。

ただし、Azure PowerShellなどを使う場合は内部的にリトライ処理が入っていてあまり問題にならないことも多いですが、独自にリクエストを投げるような処理を組み込んでいる場合は問題になる可能性が大きいです。

## 参考

https://zenn.dev/microsoft/articles/azure-api-throttling