Azure Policy で診断設定(Diagnostic settings)を配布していると、まれにリメディエーションが「In progress」のまま終わらないことがあります。本記事では原因の考え方と、運用で確実に収束させる「停止→削除→狭いスコープで再作成」の手順をまとめます。
現象の概要:診断設定の配布とリメディエーションが噛み合わない瞬間
Azure Policy の deployIfNotExists などを使って、各リソースに診断設定(Diagnostic settings)を自動作成し、Log Analytics ワークスペースへ送る設計は、監査・運用の定番です。通常は、ポリシー割り当て(assignment)→非準拠の検出→リメディエーション(修復タスク)→ARM デプロイで診断設定が作成され、最終的にタスクは成功(Succeeded)または失敗(Failed)に収束します。
ところが稀に、特定のリソースだけが、修復タスクの状態が 「In progress」(または Cancelling / In progress 系)から動かず、成功/失敗へ収束しないケースがあります。Microsoft サポートから「修復ジョブを拾ったバックエンド側ワーカーの時刻が大きくズレていた(例:数日進んでいた)ため、ジョブが期限切れと誤判定され、バックエンドでは削除扱いになる一方、キャンセル完了の状態遷移が残らず、UI 上は固まって見えた」という説明がされることがあります。
このタイプは、原因がリソース側の設定ミスではなく サービス側の“エッジケース”であるため、利用者がポリシー定義やタスク単体を調整して「二度と起きない」ようにするのは現実的ではありません。そこで、運用としては 固まったら止めて作り直す(Kill & Recreate) を標準手順にして、確実に収束させるのが最も堅牢です。
まず押さえる:同じ「In progress」でも“普通に遅いだけ”のこともある
診断設定の配布は、対象数が多いほど時間が伸びます。また、Azure Resource Manager のスロットリング、リソースプロバイダーの一時的な負荷、同時刻に走る別デプロイとの競合などで、進行がゆっくりになることもあります。大事なのは、「時間がかかっている」と「状態遷移が止まっている」を切り分けることです。
| 見え方 | よくある状況 | まずやること |
|---|---|---|
| In progress だが、デプロイ件数(成功/失敗)が増え続けている | 単に処理中。対象が多い/並列数が小さい/スロットリング | 少し待つ。並列数・スコープ設計を見直す |
| In progress のまま、デプロイ詳細が増えない・最終更新が止まっている | キューが詰まっている/バックエンドの状態遷移が欠けた | 停止→削除→狭いスコープで再作成を検討 |
| Cancelling 表示になったのに長時間変わらない | キャンセル処理が完了しない、または表示が追従していない | 削除(停止を許可)→再作成。必要ならサポートへ状況共有 |
原因の考え方:サービス側エッジケースと“リソース固有の詰まり”を分ける
サポート説明にある「ワーカーのクロックスキュー(時刻ズレ)」のように、利用者側では再現も予防も難しい事象があります。一方で、診断設定の配布には、同じように“固まって見える”が実態は別の詰まり(権限不足、ロック、既存設定との競合など)も混ざります。
| カテゴリ | 代表例 | 症状 | 見分け方(ヒント) |
|---|---|---|---|
| サービス側エッジケース | クロックスキュー、内部キューの不整合など | 少数のリソースだけが In progress で停止。再試行しても同じ挙動 | デプロイ件数が増えず、停止・削除して作り直すと通ることが多い |
| 権限(RBAC) | 割り当てのマネージド ID に必要ロールがない | 進捗が出にくい/一部だけ作成されない/作成された形跡がない | デプロイ詳細やアクティビティログに「AuthorizationFailed」等が出る |
| リソース保護 | リソースロック(Delete/ReadOnly) | 更新系デプロイが通らない/見た目が止まる | ロックが付いていないか確認(RG/リソース) |
| 診断設定の競合 | 既存の診断設定がある/名前や送信先が衝突 | 同じリソースだけいつも問題が出る | 対象リソースに既に Diagnostic settings が存在するか確認 |
| プラットフォーム制約 | 送信先の制限、同時更新競合、API の一時的制限 | タイミング依存で失敗/遅延 | 時間を空けると通る/並列数を下げると改善 |
切り分け手順:固まった前に“本当に詰まっているか”を確認する
Kill & Recreate は強力ですが、乱発すると無駄な作業も増えます。そこで、一定時間(例:1〜2時間)を超えたら、次の順序で確認すると効率が上がります。
診断設定が実際に作成されているか
UI 上のリメディエーションが固まっていても、対象リソースには診断設定が既に作成済みで、実害がないケースがあります。まずは対象リソースの「診断設定」画面(または CLI/PowerShell)で、期待する設定名と送信先(Log Analytics)が入っているか確認します。
リメディエーションのデプロイ詳細が増えているか
リメディエーションは内部的にデプロイを積み上げていきます。デプロイ一覧が増えているなら、単に遅い可能性が高いです。反対に、デプロイ一覧が増えず、失敗も成功も増えず、最終更新時刻が長時間変わらないなら、状態遷移そのものが止まっている可能性が上がります。
CLI で進捗を見る場合は、次のように remediation のデプロイ一覧を確認します(スコープは環境に合わせて読み替え)。
az policy remediation deployment list -g <rg> -n <remediationName>
権限と送信先(Log Analytics)のアクセスを再確認
診断設定を「書く」権限と、送信先(Log Analytics ワークスペース)へ「送る」権限は別です。割り当てに使っているマネージド ID が、少なくとも次を満たしているか点検します。
- 対象リソースに診断設定を作成できる(リソース側の適切なロール)
- Log Analytics ワークスペース側にも必要な権限がある(送信先の制約を満たす)
- イニシアチブの場合、対象定義が正しく remediation できる形で割り当てられている
結論:個別ジョブでの根本予防は難しい。標準手順は「Kill & Recreate」
ワーカーのクロックスキューのように、利用者側の操作では防げないサービス側レアケースがある以上、運用としては「固まったら確実に収束させる」ことに寄せるのが現実解です。具体的には、停止/削除して状態を切り直し、できるだけ狭いスコープでリメディエーションを作り直します。その後に準拠性スキャン(再評価)を走らせて、準拠状態の表示を揃えます。
| ステップ | 目的 | 判断ポイント | 期待する結果 |
|---|---|---|---|
| 監視(しきい値) | “放置すべき遅延”と“介入すべき停止”の線引き | In progress が一定時間を超過、かつ進捗がない | 介入対象が明確になる |
| 停止(キャンセル) | 走り続けるジョブを止め、後続に影響を出さない | Stop / cancel が通るか | 新規デプロイが増えなくなる |
| 削除 | UI/バックエンドの“残骸”を消す | 停止できない場合も AllowStop で削除 | 該当 remediation が一覧から消える |
| 狭いスコープで再作成 | 影響範囲を最小化し、成功率を上げる | ResourceId / LocationFilter などで絞る | 短時間で成功/失敗に収束する |
| 準拠性スキャン | 表示上の準拠状態を最新化 | 作成済みでも非準拠表示が残る場合がある | Compliance が揃う |
手順A:固まった修復タスクの「停止/削除 → 作り直し」
以下は、リソース グループ スコープでリメディエーションを作成しているケースの例です。サブスクリプションや管理グループ スコープで作っている場合は、対応するスコープ引数に読み替えてください。ポイントは、同じ巨大スコープでやり直さないことです。まずは詰まったリソースに寄せて小さく作り直し、短時間で収束させます。
PowerShell(Az)例
# 停止(キャンセル)
Stop-AzPolicyRemediation -ResourceGroupName <rg> -Name <remediationName>
# 必要なら削除(停止を許可して削除)
Remove-AzPolicyRemediation -ResourceGroupName -Name -AllowStop
# 再作成(できるだけ狭いスコープ/対象で)
Start-AzPolicyRemediation ` -PolicyAssignmentId <policyAssignmentId>`
-Name fix-xyz ` -ResourceId <resourceId>`
-ResourceDiscoveryMode ReEvaluateCompliance ` -LocationFilter <region>`
-ParallelDeploymentCount 5
Azure CLI 例
# キャンセル
az policy remediation cancel -g <rg> -n <remediationName>
# 削除
az policy remediation delete -g -n
# 再作成(できるだけ狭いスコープ/対象で)
az policy remediation create -g -n fix-xyz
--policy-assignment
--resource
--resource-discovery-mode ReEvaluateCompliance
--location-filters
補足:並列数(parallel deployments)の調整まで細かく制御したい場合は、PowerShell の -ParallelDeploymentCount を使うか、IaC(ARM/Bicep など)で remediation の parallelDeployments を指定する運用が堅実です。
作り直し時に効く“絞り込み”の考え方
「診断設定を配布したい」という目的に対して、リメディエーションは短時間で終わるほど運用が安定します。特にサービス側のレアケースは「長時間ジョブ」ほど遭遇確率が上がる体感があるため、塊を小さく分割します。
| 絞り込み方法 | 使いどころ | 期待効果 | 注意点 |
|---|---|---|---|
| ResourceId(単一リソース) | “ランダムに1個だけ”が固まった | 最小の影響で最短収束 | 原因が権限/制約の場合は同じ失敗を再現しやすい |
| LocationFilter(リージョン単位) | 対象が多すぎる/リージョンで運用が分かれている | ジョブが短くなる。スロットリングも緩和 | “グローバル”リソースは場所が合わず外れることがある |
| イニシアチブの definitionReferenceId 単位 | イニシアチブで複数ポリシーを束ねている | 原因の切り分けが速い | どの定義が該当か把握が必要 |
| ResourceDiscoveryMode の切替 | 準拠状態が古い/非準拠が変動している | 再評価してから対象確定できる | スコープや環境により挙動が異なる場合がある |
手順B:状態を揃える「準拠性スキャン(再評価)」
診断設定が作成済みでも、ポリシーの準拠性はすぐに反映されないことがあります。特に「固まった remediation を削除した」後は、表示が追従せず非準拠が残って見えることがあるため、スキャンを明示的に走らせて整合させます。
PowerShell(Az)
Start-AzPolicyComplianceScan -ResourceGroupName <rg>
Azure CLI
az policy state trigger-scan -g <rg>
予防策:再発率を下げる“運用設計”のコツ
サービス側レアケースはゼロにはできませんが、遭遇しにくい設計に寄せることはできます。キーワードは 「ジョブを短く・小さく・分割」 です。診断設定の配布は「一度に全部やる」より、「定期的に小さく回す」方が安定します。
- 巨大な一括リメディエーションを避ける(サブスクリプション全体を一気に remediate しない)
- リージョンや RG 単位で分割し、並列数を適度に抑える
- イニシアチブの場合、可能なら個別ポリシー単位で remediate して“塊”を小さくする
- 並列数を上げすぎない(速く終わらせたい気持ちと、スロットリング・競合のバランスを取る)
- 冪等性(同じ操作を何回やっても同じ結果)に寄せる:既存診断設定の有無、設定名、送信先の統一
| 設計レバー | 推奨の方向性 | 理由 | “やりすぎ”の副作用 |
|---|---|---|---|
| スコープ | 小さく分割(RG / リージョン / リソース単位) | 長時間ジョブを避けると、稀な異常条件に当たる窓が減る | 運用の手数が増える。命名ルールと自動化が重要 |
| 並列数 | 控えめから開始し、詰まりがない範囲で上げる | スロットリングや競合を避ける | 低すぎると完了が遅くなり、結果として“長時間化”する |
| 再評価 | 必要なときだけ ReEvaluateCompliance を使う | 対象の再計算で“途中状態”の影響を受けにくい | 対象数が多いと再評価自体が重くなる |
| 監視 | In progress の滞留を自動検知 | 人間が気づく前に収束させる | 誤検知で無駄なキャンセルが増える。判定条件を工夫 |
セルフヒーリング:放置しないための“自動復旧”実装例
運用で一番効くのは、固まった remediation を人手で探さずに済む仕組みです。おすすめは、定期的に remediation を一覧し、In progress が一定時間を超過しているものを自動で停止→削除→再作成するパターンです。実装先は Azure Automation、Azure Functions、GitHub Actions など、どれでも構いません。
自動復旧の判定条件(例)
- 状態が InProgress(または Cancelling)
- 開始から X 時間以上
- deployment list の件数が一定時間増えていない(可能なら)
PowerShell ひな型(概念)
環境に合わせてスコープ(管理グループ/サブスクリプション/RG)や命名規則を調整してください。ポイントは、まず狭いスコープで作り直すこと、そしてスキャンまで一気通貫で回すことです。
# 例:RG 内の remediation を監視し、一定時間超過なら作り直す(概念コード)
$rg = "<rg>"
$thresholdHours = 2
$now = Get-Date
$remediations = Get-AzPolicyRemediation -ResourceGroupName $rg
foreach ($r in $remediations) {
if ($r.ProvisioningState -in @("InProgress","Cancelling")) {
# CreatedOn / StartedOn 相当の値が取れる場合はそれを利用(取れない場合は運用側で開始時刻を記録)
$started = $r.CreatedOn
$age = $now - $started
if ($age.TotalHours -ge $thresholdHours) {
# 停止 → 削除
Stop-AzPolicyRemediation -ResourceGroupName $rg -Name $r.Name -ErrorAction SilentlyContinue
Remove-AzPolicyRemediation -ResourceGroupName $rg -Name $r.Name -AllowStop -ErrorAction SilentlyContinue
# ここで「詰まったリソース」を特定できるなら ResourceId で再作成
# できないなら LocationFilter や小さめの scope で分割して再作成する
Start-AzPolicyRemediation `
-PolicyAssignmentId "<policyAssignmentId>" `
-Name ("recreate-" + $r.Name) `
-ResourceDiscoveryMode ReEvaluateCompliance `
-LocationFilter "<region>" `
-ParallelDeploymentCount 5
}
}
}
# 最後に準拠性スキャン
Start-AzPolicyComplianceScan -ResourceGroupName $rg
Azure CLI での“滞留検知”の考え方
CLI は JSON を返すので、--query(JMESPath)で InProgress を絞り込み、シェル側で時間判定する作りがシンプルです。実環境ではフィールド名がスコープや API バージョンで揺れることがあるため、まずは次で出力を確認し、使えるフィールドを決めるのが安全です。
az policy remediation list -g <rg>
az policy remediation show -g <rg> -n <remediationName>
“固まり”に見える代表的な落とし穴(診断設定配布で特に多い)
サービス側のレアケース以外で、診断設定(Diagnostic settings)の配布で詰まりやすいポイントをまとめます。ここを潰すだけで、そもそも remediate を走らせる回数が減り、結果的に「固まり」に遭遇しにくくなります。
| 落とし穴 | 起きがちな症状 | 確認ポイント | 対処 |
|---|---|---|---|
| 割り当て ID(マネージド ID)の権限不足 | 進捗が遅い/一部だけ作成されない | 対象リソースとワークスペース双方の RBAC | 最小権限で必要ロールを付与(対象と送信先の両方) |
| 既に診断設定が存在し、名前や設定が競合 | 特定リソースだけ繰り返し問題 | 対象リソースの Diagnostic settings 一覧 | 命名ルールを統一。既存がある場合の扱い(上書き/別名)を決める |
| リソースロック | 更新系デプロイが通らない | ロックの有無(RG/リソース) | ロックポリシーと診断設定ポリシーの運用整合を取る |
| 送信先の制約(Log Analytics の設計) | 一部のみ失敗、または遅延 | ワークスペースの権限、テナント/サブスクリプション設計 | 送信先を統一し、スコープごとの責任範囲を明確化 |
| ARM の一時失敗・スロットリング | 時間を置くと成功する | アクティビティログ、デプロイ履歴 | 並列数を下げる、ジョブを分割する、時間帯をずらす |
例外化(exemption)は“最後の手段”として使う
どうしても特定の 1 リソースだけが継続的に問題を起こし、原因が解消できない場合は、一時的に Policy exemption を付けて運用を止める選択肢もあります。ただし、診断ログが欠ける状態を恒久化すると監査上のリスクが増えるため、exemption は期限付きで、後で必ず解除する運用をおすすめします。
運用チェックリスト:固まっても慌てず収束させるために
- In progress が一定時間を超えたら「進捗があるか」を確認する
- 対象リソースに診断設定が作成済みかを先に見る(実害の有無)
- 詰まりなら Stop/Cancel → Remove/Delete → 狭いスコープで再作成
- 最後に Compliance Scan を走らせて表示を揃える
- ジョブ分割・並列数・命名ルールを整え、セルフヒーリングで自動復旧する
まとめ
Azure Policy で診断設定(Diagnostic settings)を配布する運用は非常に有効ですが、稀にリメディエーションが「In progress」のまま収束しないことがあります。サービス側のエッジケースが絡む場合、個別ジョブの調整で根本解決するのは難しいため、運用の正攻法は Kill & Recreate です。止めて、消して、狭いスコープで作り直し、最後に準拠性スキャンで整合させる。これを“手順化+自動化”できれば、レアケースでも運用は安定します。

コメント