Contents
概要と利用シーン
- Azure Service Health(リソースヘルス): サブスクリプション/リージョン単位で Azure のインフラ障害やメンテナンス情報を取得できる管理 API。
- サービス別ステータス API: 各 PaaS が提供する public なエンドポイント(例:Web PubSub、Azure Databricks)から、リアルタイムの稼働状態(Healthy / Degraded / Unhealthy)を JSON で取得できる。
これらを組み合わせれば CI/CD パイプライン・Logic Apps・自動監視スクリプト に埋め込み、デプロイ前や定期チェック時に「サービスが正常か」を機械的に判定できます。
公式エンドポイントと正しい API バージョン
| サービス | エンドポイント例(プレースホルダー) | 推奨 api-version |
|---|---|---|
| Azure Service Health (ResourceHealth) | https://management.azure.com/subscriptions/{subscriptionId}/providers/Microsoft.ResourceHealth/availabilityStatuses?api-version=2024-02-01 |
2024‑02‑01(執筆時点で最新) |
| Web PubSub (Data plane) | https://{resource}.webpubsub.azure.com/api/health?api-version=2024-01-01 |
2024‑01‑01 |
| Azure Databricks (ステータスページ) | https://status.databricks.com/api/v2/status.json |
認証不要・バージョン指定なし |
※注意
Service Health の API バージョンは頻繁に更新されます。最新版は公式ドキュメントの “Versioning” ページ(Microsoft.ResourceHealth REST reference)で必ず確認してください。
認証方式のまとめ
3‑1. Azure AD トークン取得(PowerShell / Azure CLI)
| ツール | 主なコマンド例 | 補足 |
|---|---|---|
| PowerShell (Az モジュール) | Connect-AzAccount → (Get-AzAccessToken -ResourceUrl "https://management.azure.com/").Token |
Get-AzAccessToken は Azure AD アプリケーションやマネージド ID でも使用可能。 |
| Azure CLI | az account get-access-token --resource https://management.azure.com/ --query accessToken -o tsv |
Azure Cloud Shell でもそのまま実行できます。 |
正しい PowerShell サンプル
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
# 1. Azure AD にサインイン(対話式またはサービスプリンシパル) Connect-AzAccount -Tenant "<your-tenant-id>" ` -ApplicationId "<client-id>" ` -CertificateThumbprint "<thumbprint>" # 2. Management API 用のアクセストークン取得 $accessToken = (Get-AzAccessToken -ResourceUrl "https://management.azure.com/").Token # 3. トークンを使って Service Health を呼び出す例 $uri = "https://management.azure.com/subscriptions/$env:AZURE_SUBSCRIPTION_ID/providers/Microsoft.ResourceHealth/availabilityStatuses?api-version=2024-02-01" $response = Invoke-RestMethod -Uri $uri -Headers @{ Authorization = "Bearer $accessToken" } -Method Get $response | ConvertTo-Json -Depth 5 |
ポイント
Get-AzAccessTokenの-Credentialパラメータは不要です。代わりに Azure CLI と同様に-ResourceUrlを指定し、現在のコンテキストからトークンを取得します。
3‑2. マネージド ID の利用例
Azure CLI(System‑assigned Managed Identity)
|
1 2 3 4 5 6 7 8 9 |
# VM や App Service 上で実行する想定 TOKEN=$(az account get-access-token \ --resource https://management.azure.com/ \ --query accessToken -o tsv) curl -H "Authorization: Bearer $TOKEN" \ -H "Accept: application/json" \ "https://management.azure.com/subscriptions/${SUB_ID}/providers/Microsoft.ResourceHealth/availabilityStatuses?api-version=2024-02-01" |
PowerShell(Managed Identity 環境)
|
1 2 3 4 5 6 7 8 |
$token = (Invoke-RestMethod -Uri "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https%3A%2F%2Fmanagement.azure.com%2F" ` -Headers @{ Metadata = "true" } ` -Method Get).access_token Invoke-RestMethod -Uri $uri ` -Headers @{ Authorization = "Bearer $token"; Accept = "application/json" } ` -Method Get |
3‑3. Databricks ステータス API は 認証不要
Databricks が提供する https://status.databricks.com/api/v2/status.json はパブリックエンドポイントです。
- ヘッダーに Authorization を付与しない(付与しても無視されます)。
- 取得頻度は公式ドキュメントで「1 分間に最大 30 リクエスト」程度と記載されていますが、実際のレートリミットは緩やかです。
|
1 2 3 4 |
$uri = "https://status.databricks.com/api/v2/status.json" $response = Invoke-RestMethod -Uri $uri -Method Get -Headers @{ Accept = "application/json" } $response | ConvertTo-Json -Depth 3 |
レートリミットと再試行ポリシー
| API | 公開されているレートリミット(執筆時点) |
|---|---|
| Service Health (ResourceHealth) | 1 分間に最大 60 リクエスト(公式ドキュメント) |
| Web PubSub Data Plane | 1 秒あたり 10 リクエスト程度(推奨上限はサービスごとに異なるため、Retry-After ヘッダーで確認) |
| Databricks ステータス API | 明示的なリミットは無いが、過度の呼び出しは 429 (Too Many Requests) を返すことがあります |
再試行ロジック(PowerShell / Python 共通)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
function Invoke-WithRetry { param( [string]$Uri, [hashtable]$Headers, [int]$MaxAttempts = 3 ) for ($i=1; $i -le $MaxAttempts; $i++) { try { $resp = Invoke-RestMethod -Uri $Uri -Headers $Headers -Method Get -TimeoutSec 15 return $resp } catch { if ($_.Exception.Response.StatusCode.value__ -eq 429) { $retryAfter = $_.Exception.Response.Headers["Retry-After"] $waitSec = [int]($retryAfter ? $retryAfter : 5) Write-Warning "Rate limit hit – wait ${waitSec}s (attempt $i/$MaxAttempts)" Start-Sleep -Seconds $waitSec } else { throw $_ # 他のエラーは即座に再送しない } } } throw "Exceeded maximum retry attempts ($MaxAttempts) for $Uri" } |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
import time, requests def get_with_retry(url, headers, max_attempts=3): for attempt in range(1, max_attempts + 1): resp = requests.get(url, headers=headers, timeout=15) if resp.status_code == 429: # Rate limit wait = int(resp.headers.get("Retry-After", "5")) print(f"Rate limited – waiting {wait}s (attempt {attempt}/{max_attempts})") time.sleep(wait) continue resp.raise_for_status() return resp.json() raise RuntimeError(f"Maximum retry attempts exceeded for {url}") |
実装サンプル
1. PowerShell(Invoke‑RestMethod)
|
1 2 3 4 5 6 7 8 9 |
# 前提:$accessToken に有効な Azure AD トークンが格納済み $endpoint = "https://mywebpubsub.webpubsub.azure.com/api/health?api-version=2024-01-01" $response = Invoke-WithRetry -Uri $endpoint ` -Headers @{ Authorization = "Bearer $accessToken"; Accept = "application/json" } # 整形して出力 $response | ConvertTo-Json -Depth 5 |
2. Azure CLI(az rest)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
# 環境変数でサブスクリプション ID とトークンを保持 export SUB_ID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" TOKEN=$(az account get-access-token \ --resource https://management.azure.com/ \ --query accessToken -o tsv) ENDPOINT="https://management.azure.com/subscriptions/${SUB_ID}/providers/Microsoft.ResourceHealth/availabilityStatuses?api-version=2024-02-01" az rest --method GET \ --uri "$ENDPOINT" \ --header "Authorization=Bearer $TOKEN" \ --header "Accept=application/json" |
3. Python(requests)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
import os, requests, time # Azure AD トークンは環境変数 AZURE_TOKEN に設定済みと想定 token = os.getenv("AZURE_TOKEN") if not token: raise EnvironmentError("AZURE_TOKEN が未設定です") headers = { "Authorization": f"Bearer {token}", "Accept": "application/json" } # Web PubSub のヘルスチェック例 url = "https://mywebpubsub.webpubsub.azure.com/api/health?api-version=2024-01-01" data = get_with_retry(url, headers) print(data) # pretty‑print したい場合は json.dumps(..., indent=2) |
4. Databricks ステータス(認証不要)
|
1 2 3 4 |
$uri = "https://status.databricks.com/api/v2/status.json" $databricksStatus = Invoke-RestMethod -Uri $uri -Method Get -Headers @{ Accept = "application/json" } $databricksStatus | ConvertTo-Json -Depth 3 |
|
1 2 3 4 5 6 |
import requests resp = requests.get("https://status.databricks.com/api/v2/status.json", timeout=10) resp.raise_for_status() print(resp.json()) |
レスポンス解析とエラーハンドリング
主な JSON フィールド(共通)
| フィールド | 型 | 意味 |
|---|---|---|
status |
string | "Healthy" / "Degraded" / "Unhealthy" |
title |
string | 人間が読める要約メッセージ |
details |
array (任意) | 障害時の詳細情報 |
timestamp |
ISO8601 | データ取得時刻 |
PowerShell 判定ロジック
|
1 2 3 4 5 6 7 |
switch ($response.status) { "Healthy" { Write-Host "✅ 正常です。" -ForegroundColor Green } "Degraded" { Write-Warning "⚠️ 警告状態: $($response.title)" } "Unhealthy" { Write-Error "❌ 障害発生!詳細: $($response.details | ConvertTo-Json -Depth 2)" } default { Write-Warning "未知のステータス : $($response.status)" } } |
Python 判定ロジック
|
1 2 3 4 5 6 7 8 9 10 |
status = data["status"] if status == "Healthy": print("✅ Healthy") elif status == "Degraded": print(f"⚠️ Degraded – {data.get('title')}") elif status == "Unhealthy": raise RuntimeError(f"❌ Unhealthy – {data.get('title')} / details: {data.get('details')}") else: print(f"🤔 Unknown status: {status}") |
タイムアウト・例外処理のベストプラクティス
| 言語 | 推奨タイムアウト | 失敗時の対応 |
|---|---|---|
PowerShell (Invoke-RestMethod) |
-TimeoutSec 15 |
try / catch で System.Net.WebException を捕捉し、リトライロジックへ流す |
Azure CLI (az rest) |
デフォルトは 60 秒 → 必要に応じて --max-request-timeout オプションで調整 |
エラーコードを $? で判定 |
Python (requests) |
timeout=10(秒) |
requests.exceptions.Timeout をキャッチし、再試行またはアラート送信 |
Log Analytics への連携例
Data Collector API の構成
| 項目 | 内容 |
|---|---|
| エンドポイント | https://<workspace-id>.ods.opinsights.azure.com/api/logs?api-version=2016-04-01 |
| 認証方式 | Shared Key(Primary または Secondary キー) |
| カスタムログタイプ | 任意(例:AzureServiceHealth) |
PowerShell 実装
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
# 1. 必要情報取得 $workspaceId = "<LogAnalyticsWorkspaceId>" $sharedKey = "<PrimaryOrSecondaryKey>" $jsonBody = $response | ConvertTo-Json -Depth 5 # 2. 認証ヘッダー作成(HMAC SHA256) $date = (Get-Date).ToUniversalTime().ToString("r") $contentLen = [Text.Encoding]::UTF8.GetByteCount($jsonBody) $stringToHash = "POST`n$contentLen`napplication/json`nx-ms-date:$date`n/api/logs" $bytesToHash = [Text.Encoding]::ASCII.GetBytes($stringToHash) $keyBytes = [Convert]::FromBase64String($sharedKey) $hash = [System.Security.Cryptography.HMACSHA256]::new($keyBytes).ComputeHash($bytesToHash) $signature = "SharedKey $workspaceId:" + [Convert]::ToBase64String($hash) # 3. HTTP POST $headers = @{ Authorization = $signature "Log-Type" = "AzureServiceHealth" "x-ms-date" = $date "Content-Type"= "application/json" } Invoke-RestMethod -Method Post ` -Uri "https://$workspaceId.ods.opinsights.azure.com/api/logs?api-version=2016-04-01" ` -Body $jsonBody -Headers $headers |
ポイント
Log-Typeは英数字とアンダースコアのみ使用可。Kusto クエリでAzureServiceHealth_CLのように自動的にサフィックス_CLが付与されます。
Kusto 例:障害が発生したレコードだけ抽出
|
1 2 3 4 |
AzureServiceHealth_CL | where status_s == "Unhealthy" | summarize count() by bin(timestamp_t, 5m), title_s |
CI/CD パイプラインでの前提チェック実装例
GitHub Actions(Python スクリプト呼び出し)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
name: Check Service Health before Deploy on: workflow_dispatch: pull_request: jobs: health-check: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Install Python deps run: pip install requests - name: Acquire Azure AD token (service principal) env: AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }} AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }} AZURE_CLIENT_SECRET: ${{ secrets.AZURE_CLIENT_SECRET }} run: | az login --service-principal -u $AZURE_CLIENT_ID -p $AZURE_CLIENT_SECRET --tenant $AZURE_TENANT_ID export AZURE_TOKEN=$(az account get-access-token --resource https://management.azure.com/ --query accessToken -o tsv) echo "AZURE_TOKEN=$AZURE_TOKEN" >> $GITHUB_ENV - name: Run health‑check script env: AZURE_TOKEN: ${{ env.AZURE_TOKEN }} run: | python scripts/check_service_health.py # スクリプトはステータスが Unhealthy の場合に exit 1 を返すよう実装 - name: Deploy (only if healthy) if: success() uses: azure/arm-deploy@v1 with: scope: subscription # ... 省略 ... |
Azure DevOps(AzureCLI@2 タスク)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
trigger: none stages: - stage: PreCheck jobs: - job: HealthCheck pool: vmImage: 'ubuntu-latest' steps: - task: AzureCLI@2 name: GetToken inputs: azureSubscription: 'MyServiceConnection' scriptType: bash scriptLocation: inlineScript inlineScript: | token=$(az account get-access-token --resource https://management.azure.com/ --query accessToken -o tsv) echo "##vso[task.setvariable variable=AZURE_TOKEN]$token" - task: Bash@3 name: RunCheck inputs: targetType: 'inline' script: | curl -H "Authorization: Bearer $(AZURE_TOKEN)" \ -H "Accept: application/json" \ "https://management.azure.com/subscriptions/${SUB_ID}/providers/Microsoft.ResourceHealth/availabilityStatuses?api-version=2024-02-01" continueOnError: false # エラーが出たらパイプラインは失敗 - stage: Deploy dependsOn: PreCheck condition: succeeded() jobs: - deployment: DeployResources pool: vmImage: 'ubuntu-latest' environment: 'prod' strategy: runOnce: deploy: steps: # デプロイ手順を記述 … |
ベストプラクティスとトラブルシューティング
| 項目 | 推奨設定・対策 |
|---|---|
| API バージョン管理 | スクリプト内に定数として ApiVersion を保持し、変更があれば CI で自動検出できるようテストを追加。 |
| 認証情報の安全な保管 | サービスプリンシパルは Key Vault に格納し、az keyvault secret show で取得して使用する。マネージド ID が利用可能なら必ず採用。 |
| レートリミット回避 | 1 分あたりの呼び出し上限を超えそうな場合は Azure Scheduler または Logic Apps の Recurrence トリガーで間隔を調整する。 |
| ロギング | API 呼び出し前後に必ず requestId(x-ms-request-id)とステータスコードをログへ残す。障害解析が楽になる。 |
| テスト自動化 | pester(PowerShell)や pytest(Python)で「Healthy が返ってくること」をユニットテストに組み込み、PR 時に検証。 |
| エラーメッセージの国際化 | 画面表示とログは英語ベースで統一し、日本語メッセージは別途ローカライズ用ファイルに切り出す。 |
| タイムゾーン | timestamp は常に UTC(ISO8601)になるので、レポートやダッシュボードでは必要に応じてローカル時刻へ変換する (DateTime.ToLocalTime())。 |
よくある失敗例と対処法
| 症状 | 原因 | 解決策 |
|---|---|---|
401 Unauthorized が返る |
アプリ登録に API 権限 が付与されていない、または同意が取れていない | Azure Portal → App registration → API permissions で Azure Service Management (user_impersonation) を追加し、管理者に同意させる。 |
429 Too Many Requests が頻発 |
複数スクリプトが同時実行/レートリミット設定を無視している | 共通の RateLimiter ライブラリ(例:Polly for .NET、tenacity for Python)で制御。 |
| JSON の構造が変わったときにエラーになる | サービス側でステータス API のレスポンス形式を更新した | スキーマバリデーション (jq や jsonschema) を追加し、変更検知時は CI で警告。 |
| Log Analytics に送れない | Shared Key が間違っているか、有効期限が切れている | キーのローテーション手順を自動化(Key Vault のシークレット更新 → スクリプト再取得)。 |
参考リンク
| 内容 | URL |
|---|---|
| Azure Resource Health REST API (最新版) | https://learn.microsoft.com/en-us/rest/api/resourcehealth/ |
| Web PubSub Data Plane API – health エンドポイント | https://learn.microsoft.com/azure/azure-web-pubsub/howto-manage-service#check-service-health |
| Databricks Status API(認証不要) | https://status.databricks.com/api/v2/status.json |
| Azure Monitor の Rate Limits | https://learn.microsoft.com/azure/azure-monitor/limits |
| Log Analytics Data Collector API | https://learn.microsoft.com/azure/monitor/logs/data-collector-api |
| PowerShell Az モジュール – Get-AzAccessToken | https://learn.microsoft.com/powershell/module/az.accounts/get-azaccesstoken |
| Azure CLI – az rest | https://learn.microsoft.com/cli/azure/rest?view=azure-cli-latest |
まとめ
- 最新 API バージョン を必ず公式ドキュメントで確認し、スクリプトにハードコーディングしない。
- 認証は Azure AD トークンかマネージド ID を利用するが、Databricks のステータス API は例外的に認証不要。
- レートリミット(1 分 60 リクエスト)を意識し、
Retry-Afterヘッダーで再試行ロジックを実装。 - コードは一貫したインデント・引用符 を保ち、PowerShell の
Get-AzAccessToken使用例は正しく記述する。 - 取得結果は Log Analytics カスタムログ に送信し、Kusto クエリや Logic Apps と連携すればアラート自動化が完結。
- CI/CD 前提チェック を組み込むことで、障害中のデプロイ失敗リスクを大幅に低減できる。
上記手順とサンプルコードをベースに、貴社環境へ 「サービスステータス取得 → 監視 → アラート」 のフローを実装すれば、Azure 全体の可用性管理がシームレスになります。ぜひリポジトリにある scripts/ ディレクトリをクローンし、環境変数や Key Vault の設定だけで動作確認してみてください。