Azure Site Recovery(ASR)で自動フェールオーバーをRunbook化した際、Webhook呼び出しからRecovery Planの非計画フェールオーバーを開始しようとして「Error 506: An invalid parameter ReplicationProviderInput was passed.」に遭遇するケースがあります。本記事では原因の本質、正しいinstanceTypeの見つけ方、堅牢なRunbookの書き方までを実運用の視点で網羅的に解説します。
エラーの全体像と結論(TL;DR)
結論:JSONボディのproviderSpecificDetails[].instanceTypeが、保護対象VM実体の「レプリケーション プロバイダー」と一致していないことがError 506の最頻出原因です。InMageAzureV2を固定指定しているサンプルをA2A環境に流用すると、instanceType不一致によりReplicationProviderInputが不正と解釈されます。対象VM(またはRecovery Plan配下すべてのVM)の実プロバイダーに合わせてinstanceTypeを設定すれば解消します。
代表的なマッピング
| シナリオ | 指定すべき instanceType | 代表用途 |
|---|---|---|
| Azure VM → Azure(リージョン間) | A2A | Azure-to-Azure(A2A)レプリケーション |
| VMware/物理 → Azure | InMageAzureV2 | オンプレのvSphere/物理サーバー保護 |
| オンプレ Hyper‑V → Azure | HyperVReplicaAzure | オンプレHyper‑Vの保護 |
※Recovery Plan配下にプロバイダーの異なるVMが混在している場合、providerSpecificDetailsにはVM群のプロバイダー構成に沿った要素を用意する必要があります(後述の自動判別ロジックを参照)。
なぜ Error 506 が出るのか:ASRの「プロバイダー依存入力」
ASRのフェールオーバー開始API(Recovery Planや個別VMに対するUnplanned Failover)では、共通のパラメーターに加えて、providerSpecificDetailsとしてレプリケーションプロバイダー固有の入力が必要になります。ここに誤ったinstanceTypeや、プロバイダーに存在しないパラメーターを渡すと、ASRは入力を正しくバインドできず、ReplicationProviderInputが不正という汎用エラー(Error 506)として返します。
例えばA2Aで有効なrecoveryPointTypeは、InMageAzureV2ではrecoveryPointIdの指定が主であるなど、期待するボディ構造が明確に異なります。よって、まずはinstanceTypeの一致、続いてプロバイダー固有プロパティの正当性を検証するのが近道です。
正しい instanceType を見つける実務手順
ポータルで確認する(もっとも簡単)
- Azureポータル → Recovery Servicesコンテナー → レプリケートされたアイテムを開きます。
- 対象VMの一覧で「レプリケーション プロバイダー」列を確認し、表示される値(例:
A2A/InMageAzureV2/HyperVReplicaAzure)をメモします。 - Recovery Planで実行する場合は、Recovery Plan配下の全VMを開き、プロバイダーが混在していないかチェックします。
PowerShellで確認する(自動化向け)
Runbookから自動判別するには、ASRの保護対象アイテム(RPI: Replication Protected Item)を列挙し、ProviderSpecificDetails.InstanceTypeまたはProviderName相当の値を読み取ります。
# 前提: AutomationアカウントのManaged Identityに「Site Recovery オペレーター」以上の権限
Connect-AzAccount -Identity
# Recovery Services Vault のコンテキスト設定
$vaultName = "<VaultName>"
$vaultRg = "<VaultResourceGroup>"
Set-AzRecoveryServicesAsrVaultContext -Vault $vaultName -ResourceGroupName $vaultRg
# Recovery Plan配下のRPIを取得(単一VMの場合は対象RPIのみでOK)
$rpName = "<RecoveryPlanName>"
$rp = Get-AzRecoveryServicesAsrRecoveryPlan -Name $rpName
# Recovery Planに含まれるRPIを展開してプロバイダーを把握
$rpis = foreach ($group in $rp.Groups) {
foreach ($member in $group.ReplicationProtectedItems) {
Get-AzRecoveryServicesAsrReplicationProtectedItem -Id $member.Id
}
}
# VMごとのInstanceType一覧を確認
$rpis | Select-Object FriendlyName, @{N="InstanceType";E={$_.ProviderSpecificDetails.InstanceType}}
この一覧結果に基づき、RunbookではproviderSpecificDetailsの配列を組み立てます。
最小修正で通す:A2A の非計画フェールオーバー例
もっとも多い例として、A2A環境でinstanceTypeをA2Aに修正し、A2Aで有効なプロパティ(例:recoveryPointType)を渡す構成です。Recovery Planに対してUnplanned Failoverを開始するREST呼び出しの概形を示します。
$subId = "<SubscriptionId>"
$vaultName = "<VaultName>"
$vaultRg = "<VaultResourceGroup>"
$rpName = "<RecoveryPlanName>"
$apiVersion = "2025-02-01"
Connect-AzAccount -Identity
$token = (Get-AzAccessToken -ResourceUrl "https://management.azure.com/").Token
$headers = @{ Authorization = "Bearer $token"; "Content-Type" = "application/json" }
$uri = "https://management.azure.com/subscriptions/$subId/resourceGroups/$vaultRg/providers/Microsoft.RecoveryServices/vaults/$vaultName/replicationRecoveryPlans/$rpName/unplannedFailover?api-version=$apiVersion"
$body = @{
properties = @{
failoverDirection = "PrimaryToRecovery"
sourceSiteOperations = "Required"
providerSpecificDetails = @(
@{
instanceType = "A2A"
recoveryPointType = "Latest" # "Latest" | "LatestProcessed" | "LatestApplicationConsistent"
}
)
}
} | ConvertTo-Json -Depth 8
Invoke-RestMethod -Method Post -Uri $uri -Headers $headers -Body $body
ポイントはinstanceTypeを実プロバイダーに合わせること。A2AならA2A、InMageAzureV2環境なら後述のInMage用ボディに変えることでError 506が解消します。
InMageAzureV2/HyperVReplicaAzure の差異
プロバイダーごとに受け付けるプロパティが異なります。以下は典型的な最小例です(環境により追加パラメーターが必要な場合があります)。
InMageAzureV2 の例
{
"properties": {
"failoverDirection": "PrimaryToRecovery",
"sourceSiteOperations": "Required",
"providerSpecificDetails": [
{
"instanceType": "InMageAzureV2",
"recoveryPointId": "<RecoveryPointId>"
}
]
}
}
HyperVReplicaAzure の例
{
"properties": {
"failoverDirection": "PrimaryToRecovery",
"sourceSiteOperations": "Required",
"providerSpecificDetails": [
{
"instanceType": "HyperVReplicaAzure"
}
]
}
}
Hyper-Vはシンプルな場合が多いですが、計画/非計画、復旧ポイントの扱いによって追加パラメータが出ることがあります。
Recovery Plan に異種プロバイダーが混在する場合
大規模環境では、同一のRecovery PlanにA2AとInMageが混在することがあります。この場合、providerSpecificDetailsを複数要素で構成し、ASRが内部で適切にマッピングできるようにします。安全なのは、Runbook側で事前にRPIごとにプロバイダーを集計し、重複のないinstanceTypeの組み合わせを配列化する方式です。
# $rpis は前掲の取得コードで得たRPI一覧
$providerSet = $rpis | ForEach-Object { $_.ProviderSpecificDetails.InstanceType } | Sort-Object -Unique
$psd = @()
foreach ($p in $providerSet) {
switch ($p) {
"A2A" {
$psd += @{ instanceType = "A2A"; recoveryPointType = "Latest" }
}
"InMageAzureV2" {
$psd += @{ instanceType = "InMageAzureV2"; recoveryPointId = "<RecoveryPointId>" }
}
"HyperVReplicaAzure" {
$psd += @{ instanceType = "HyperVReplicaAzure" }
}
default {
throw "未対応プロバイダー: $p"
}
}
}
$body = @{ properties = @{
failoverDirection = "PrimaryToRecovery"
sourceSiteOperations = "Required"
providerSpecificDetails = $psd
}} | ConvertTo-Json -Depth 8
注意点として、InMage系では事前に復旧ポイントの選定(recoveryPointIdの決定)が必要です。これを自動化する場合、最新のアプリ整合ポイントやユーザー指定のポイントを取得して埋め込みます。
Runbook(Webhook)設計の実装パターン
Webhookペイロードの例
Runbookの使い勝手を高めるには、Webhookから実行時パラメーターを受け取る設計が有効です。
{
"subscriptionId": "<SubscriptionId>",
"vaultResourceGroup": "<RG>",
"vaultName": "<Vault>",
"recoveryPlanName": "RP-Prod-EastUS",
"failoverDirection": "PrimaryToRecovery",
"provider": "auto", // "A2A" 等の固定指定も許容
"a2aRecoveryPointType": "Latest",
"inmageRecoveryPointId": null
}
堅牢化の要点
- 入力検証:許容値(
Latest/LatestProcessed/LatestApplicationConsistentなど)をバリデーション。 - 認証:AutomationアカウントのManaged IdentityにVaultスコープでSite Recovery オペレーター以上を付与。必要に応じてリソースグループ/サブスクリプションレベルのロールも検討。
- ネットワーク:Automationアカウントから管理プレーン(management.azure.com)へ到達できること。Private Endpointや防火壁を用いる場合は許可設定を事前検証。
- Idempotency:同一RPに対する二重実行を避けるため、直近のASRジョブ状態を確認し、実行中はスキップ/待機/中断を選択できるようにする。
- ログ/監査:フェールオーバー開始前後で、Recovery Plan名、VM一覧、選定した
providerSpecificDetails、返却されたJob IdをLog Analyticsへ出力。運用監査の証跡になります。
完成度の高いRunbookサンプル(自動判別+フェールオーバー実行)
以下はA2A/InMage/HyperVを自動判別し、最小情報で非計画フェールオーバーを発火する一例です。運用環境では必ず例外処理・リトライ・ジョブ監視を追加してください。
param(
[Parameter(Mandatory=$false)]
[string]$WebhookData
)
# Webhook入力を受け取る
if ($WebhookData) {
$payload = (ConvertFrom-Json -InputObject $WebhookData)
}
$subscriptionId = $payload.subscriptionId
$vaultRg = $payload.vaultResourceGroup
$vaultName = $payload.vaultName
$recoveryPlanName = $payload.recoveryPlanName
$direction = if ($payload.failoverDirection) { $payload.failoverDirection } else { "PrimaryToRecovery" }
$providerMode = if ($payload.provider) { $payload.provider } else { "auto" }
$a2aRptype = if ($payload.a2aRecoveryPointType) { $payload.a2aRecoveryPointType } else { "Latest" }
$inmageRpid = $payload.inmageRecoveryPointId
$apiVersion = "2025-02-01"
# 認証
Connect-AzAccount -Identity | Out-Null
Select-AzSubscription -SubscriptionId $subscriptionId | Out-Null
# Vaultコンテキスト設定
Set-AzRecoveryServicesAsrVaultContext -Vault $vaultName -ResourceGroupName $vaultRg
# Recovery Plan/配下VMの解析
$rp = Get-AzRecoveryServicesAsrRecoveryPlan -Name $recoveryPlanName
$rpis = foreach ($g in $rp.Groups) {
foreach ($m in $g.ReplicationProtectedItems) {
Get-AzRecoveryServicesAsrReplicationProtectedItem -Id $m.Id
}
}
$providers = $rpis | ForEach-Object { $_.ProviderSpecificDetails.InstanceType } | Sort-Object -Unique
# providerSpecificDetails を確定
$psd = @()
if ($providerMode -ne "auto") {
$providers = @($providerMode)
}
foreach ($p in $providers) {
switch ($p) {
"A2A" {
$psd += @{ instanceType = "A2A"; recoveryPointType = $a2aRptype }
}
"InMageAzureV2" {
if (-not $inmageRpid) { throw "InMageAzureV2 には recoveryPointId の指定が必要です。" }
$psd += @{ instanceType = "InMageAzureV2"; recoveryPointId = $inmageRpid }
}
"HyperVReplicaAzure" {
$psd += @{ instanceType = "HyperVReplicaAzure" }
}
default {
throw "未対応プロバイダー: $p"
}
}
}
$body = @{ properties = @{
failoverDirection = $direction
sourceSiteOperations = "Required"
providerSpecificDetails = $psd
}} | ConvertTo-Json -Depth 8
# REST呼び出し
$token = (Get-AzAccessToken -ResourceUrl "https://management.azure.com/").Token
$headers = @{ Authorization = "Bearer $token"; "Content-Type" = "application/json" }
$uri = "https://management.azure.com/subscriptions/$subscriptionId/resourceGroups/$vaultRg/providers/Microsoft.RecoveryServices/vaults/$vaultName/replicationRecoveryPlans/$recoveryPlanName/unplannedFailover?api-version=$apiVersion"
$resp = Invoke-RestMethod -Method Post -Uri $uri -Headers $headers -Body $body
# 結果の要約出力(ログ出力は適宜Log Analyticsへ)
Write-Output ("Started Unplanned Failover. RP={0} PSD={1}" -f $recoveryPlanName, ($psd | ConvertTo-Json -Depth 5))
APIバージョン/RBAC/ネットワークの実務チェック
- APIバージョン:
2025-02-01相当の最新系で問題ありません。Vaultがサポートする範囲で固定化または変数化し、将来更新に備えてください。 - RBAC:AutomationのManaged Identityに、VaultスコープでSite Recovery オペレーター(またはそれ以上)を付与。加えて、リソースグループ/サブスクリプションへの読み取り権限が不足していないか確認します。
- ネットワーク:管理プレーン(management.azure.com)と回復先リソースへのアクセスが必要です。Private Linkや制限付きアウトバウンドを使う場合は名前解決/NSG/Firewallの例外を準備。
トラブルシューティング:Error 506 の切り分け手順
- JSON構造の検証:
properties.failoverDirectionとproperties.providerSpecificDetailsの位置が正しいか、大文字小文字を含めて再点検。 - instanceType一致:ポータルまたはPowerShellでVMのプロバイダーを確認し、Runbookの
instanceTypeが一致しているか。 - 固有パラメーター:A2Aなら
recoveryPointType、InMageならrecoveryPointIdなど、プロバイダーに応じたプロパティを載せているか。 - Recovery Plan混在:複数プロバイダー混在時、
providerSpecificDetailsに必要な種類をすべて含めたか。 - 権限不足:RBACエラーと見分けがつきにくいことがあります。ジョブ/アクティビティログ側のステータスでAccessDeniedの兆候がないか確認。
- API差分:環境により旧API準拠のVaultが存在します。APIバージョンを切り替えたり、Azモジュールのコマンドレットで成功するか(REST差分切り分け)を確認。
非計画(Unplanned)/計画(Planned)/テスト(Test)の違いと注意点
| 種別 | 典型用途 | 主なパラメータ | 注意点 |
|---|---|---|---|
| 非計画(Unplanned) | 本番障害時の切替 | failoverDirection、providerSpecificDetailsA2A: recoveryPointType | ソース側でシャットダウンできない前提。事前にRecovery Planの順序・手動アクションを整備。 |
| 計画(Planned) | 計画停止時の切替 | 基本はUnplannedに近い | ダウンタイム短縮のため、同期状態/ヘルスの事前確認をRunbookに組み込むと安全。 |
| テスト(Test) | DR演習、検証 | レプリカネットワーク、テストサブネット等 | 本番と隔離するネットワーク設計。クリーンアップRunbookも併せて用意。 |
品質強化:実運用で効くベストプラクティス
- リトライと指数バックオフ:管理プレーンの一時的な429/5xxに備えて再試行実装。
- ジョブ監視:返却されたASRジョブIDをポーリングし、最終状態(Succeeded/Failed)をTeamsやメールに通知。
- プレチェックRunbook:直前にヘルス/レプリケーション遅延/ネットワーク到達性を検査し、Fail条件なら中断。
- タグ駆動:VMやリソースグループのタグで故障系(優先順、許容停止時間)をRunbookに渡し、Recovery Planの手順分岐に活用。
- 構成ドリフト検出:Recovery Plan配下VMと実在VMの差分、ディスク/ネットワーク構成の齟齬を定期点検。
よくある落とし穴(回避のチェックリスト)
| 落とし穴 | 症状 | 対処 |
|---|---|---|
InMageAzureV2をA2A環境に流用 | Error 506 | instanceType = "A2A"に変更し、recoveryPointTypeを指定 |
| JSONの大文字小文字不一致 | バインド失敗 | スキーマ通りにproperties配下の綴りを統一 |
| 混在プロバイダー未考慮 | 一部VMだけ失敗 | providerSpecificDetailsに必要種類をすべて含める |
| RBAC不足 | 失敗時メッセージが曖昧 | Managed IdentityにVaultスコープのロールを付与 |
| 復旧ポイント未指定(InMage) | 検証段階で失敗 | 最新/指定のrecoveryPointIdを事前取得して設定 |
検証手順(再現→修正→確認)
- 再現:サンプルRunbookで
instanceType = "InMageAzureV2"固定のままA2A環境のRecovery Planに対して非計画FOを実行し、Error 506が出ることを確認。 - 修正:RunbookのJSONボディを
instanceType = "A2A"へ変更し、recoveryPointType = "Latest"を付与。 - 確認:レスポンスのジョブIDとVaultのジョブ一覧から、非計画フェールオーバーが開始状態へ遷移したことを確認。Recovery Planのステップが順次進行することを監視。
セキュリティと運用設計の補足
- 権限の最小化:Runbookは必要最小限のVault権限に限定。オーナー権限の付与は避ける。
- 監査ログ:だれが・いつ・どのRecovery Planを実行したか、Webhook呼び出し元IPやリクエストIDを含めて記録。
- ロール分離:フェールオーバー起動者とRunbook編集者のロールを分離し、ヒューマンエラーを抑止。
- 運用演習:テストフェールオーバーRunbookを定例で回し、実本番切替Runbookとの乖離がないか継続的に検証。
まとめ
ASRの非計画フェールオーバーをRunbook経由で自動化する際のError 506は、ほぼ常にproviderSpecificDetails.instanceTypeの不一致、またはプロバイダー固有パラメーターの欠落が原因です。ポータル/PowerShellで実プロバイダーを厳密に同定し、JSONボディをそれに合わせるだけで、エラーは解消します。A2AならinstanceType = "A2A"、InMageならrecoveryPointIdを忘れない、といった基本をRunbookに自動化ロジックとして組み込み、権限・ネットワーク・監査・リトライ・ジョブ監視まで含めた実運用に耐える設計に仕上げておくと、障害時の初動を大幅に短縮できます。
付録:すぐに使える最小JSONテンプレート集
A2A(非計画FO)
{
"properties": {
"failoverDirection": "PrimaryToRecovery",
"sourceSiteOperations": "Required",
"providerSpecificDetails": [
{
"instanceType": "A2A",
"recoveryPointType": "Latest"
}
]
}
}
InMageAzureV2(非計画FO)
{
"properties": {
"failoverDirection": "PrimaryToRecovery",
"sourceSiteOperations": "Required",
"providerSpecificDetails": [
{
"instanceType": "InMageAzureV2",
"recoveryPointId": "<RecoveryPointId>"
}
]
}
}
HyperVReplicaAzure(非計画FO)
{
"properties": {
"failoverDirection": "PrimaryToRecovery",
"sourceSiteOperations": "Required",
"providerSpecificDetails": [
{
"instanceType": "HyperVReplicaAzure"
}
]
}
}
補足Q&A
Q. APIバージョンは固定でよい?
A. 環境が対応していれば2025-02-01で問題ありません。将来の互換性のため、Runbookではバージョンを変数化しておくと保守が容易です。 Q. Recovery Plan配下にA2AとInMageが混在しているが、一つのJSONで開始できる?
A. 可能です。providerSpecificDetailsを配列で用意し、必要なinstanceTypeごとに要素を追加します。InMage要素には適切なrecoveryPointIdを付けてください。 Q. Runbookの権限は何を付ければよい?
A. AutomationアカウントのManaged IdentityにVaultスコープでSite Recovery オペレーター以上を割り当てます。加えて、対象リソースの読み取りができるよう必要に応じて権限を補完します。 Q. 「Latest」と「LatestProcessed」の違いは?(A2A)
A. Latestは可能な限り最新を目指す復旧ポイント、LatestProcessedはサービス側で処理済みの直近ポイントを指します。RPOや一貫性要件に応じて使い分けます。

コメント