この記事では、Bicepとデプロイ スクリプトを使用して、リソース プロパティが特定の値を返すまでデプロイを一時停止する方法について説明します。 この手法を使用すると、デプロイされたリソースが準備ができているが、基になるリソースが存在しないことをAzure Resource Manager報告した場合に、デプロイが成功することを確認できます。 この場合、デプロイされたリソースはまだデプロイの残りの部分と対話する準備ができていません。つまり、一時停止が必要です。
この記事では、Azure Virtual WANシナリオを使用して手法を示します。 次のファイルには、リソース チェックと一時停止の実装が含まれています。
デプロイに合わせてファイルを調整できます。 役に立つよう、azResourceStateCheck.bicep モジュールはパラメーター化されています。
dependsOn プロパティは、vwanvhcs.bicep モジュールのデプロイが azResourceStateCheck.bicep モジュールのデプロイに依存していることを確認するために、orchestration.bicep で使用されます。
Architecture
このアーキテクチャのVisio ファイルをダウンロードしてください。
このアーキテクチャについては、 GitHub のコード サンプル を確認してダウンロードします。
サブスクリプション スコープでのリソース マネージャーへのデプロイ用に、orchestration.bicepファイルを送信します。
Note
このBicep ファイルと、この例で使用されるその他のファイルは、infra/samples/deployment-scripts-property-check ディレクトリから取得できます。 リポジトリ内のファイルの部分的な編成がアーキテクチャ図の右側に表示されます。
orchestration.bicep ファイルは、サブスクリプション スコープでリソース グループを作成します。
orchestration.bicep ファイルは、Virtual WANとスポーク仮想ネットワークをデプロイします。
orchestration.bicep は vwan.bicep モジュールをデプロイし、リソース グループ スコープにVirtual WANをデプロイします。
orchestration.bicep は、vnet.bicep モジュールをデプロイし、リソース グループ スコープに仮想ネットワークをデプロイします。
Virtual WANとスポークの仮想ネットワークは、Bicepによって互いに独立していると見なされるため、並列に展開されます。 依存関係によって、Bicep でのデプロイの順序が決まります。 リソースは、それに依存するリソースの前にデプロイされます。 明示的な依存関係や暗黙的な依存関係など、Bicep のリソース依存関係の詳細については、「 Bicep のリソース依存関係」を参照してください。
orchestration.bicep ファイルは、vwanhub.bicep モジュールをデプロイし、リソース グループ スコープにVirtual WAN ハブをデプロイします。 ハブはVirtual WANに暗黙的に依存します。つまり、ハブのデプロイは、Virtual WANのデプロイが完了した後にのみ行われます。
orchestration.bicep ファイルは azResourceStateCheck.bicep モジュールをデプロイします。これにより、ユーザー割り当てマネージド ID が作成され、Azureロールベースのアクセス制御 (RBAC) 閲覧者ロールがリソース グループに割り当てられます。
azResourceStateCheck.bicep モジュールは 、デプロイ スクリプト リソースをデプロイします。
デプロイ スクリプト リソースは、Resource Manager認証にユーザー割り当てマネージド ID を使用します。 その後、リソースは PowerShell デプロイ スクリプトを実行 Invoke-AzResourceStateCheck.ps1。 デプロイ スクリプトの詳細については、「 Bicep でのデプロイ スクリプトの使用」を参照してください。
このスクリプトは、Virtual WAN ハブ
routingStateプロパティをポーリングして、値がProvisionedかどうかを判断します。プロパティ値が
Provisionedされていない場合、スクリプトは orchestration.bicep ファイルで設定されたパラメーターによって指定された期間一時停止し、azResourceStateCheck.bicep モジュールに渡されます。 その後、スクリプトはroutingStateプロパティ値をもう一度チェックします。スクリプトは、一時停止とチェックのサイクルを繰り返します。 orchestration.bicep ファイルのパラメーターによって、イテレーションの最大数が決まります。 イテレーションの最大数の後にプロパティ値が
Provisionedでない場合、スクリプトは例外を生成して終了します。これにより、Bicep展開の残りの部分が停止して失敗します。プロパティ値が
Provisioned場合、デプロイ スクリプトは成功コード(0)で終了します。
デプロイ スクリプトが成功した場合、orchestration.bicep ファイルは vwanvhcs.bicep モジュールをデプロイします。これによって、スポーク仮想ネットワークとVirtual WAN ハブ間の接続が作成されます。
orchestration.bicep 内の vwanvhcs.bicep モジュールの定義には、azResourceStateCheck.bicep モジュールの正常な完了に明示的に依存する vwanvhcs.bicep を引き起こす
dependsOn句があります。 したがって、接続は、routingStateプロパティがProvisionedされている場合にのみ作成されます。vwanvhcs.bicep モジュールは、1 つのVirtual WAN ハブに対して並列デプロイがサポートされていないため、並列ではなく、Virtual WAN ハブ接続を順番にデプロイします。 バッチ サイズを
1に設定するために、モジュールは BicepbatchSizeデコレーター@batchSize(1)を使用します。 このデコレーターにより、接続が一度に 1 つずつデプロイされます。
シナリオの詳細
このアーキテクチャの重要な部分は、デプロイ スクリプト リソースをデプロイする azResourceStateCheck.bicep モジュールと、関連するデプロイ スクリプト Invoke-AzResourceStateCheck.ps1(PowerShell ファイル) です。 このモジュールでは、デプロイ スクリプトを使用してリソース プロパティの値を確認します。 この例では、リソースは Virtual WAN ハブです。
dependsOn を使用すると、1 つのモジュールを別のモジュールに明示的に依存させることができます。この環境は、Bicep モジュールを使用する 1 つのファイルからデプロイされるためです。 この例では、 dependsOn 、vwanvhcs.bicep モジュールが azResourceStateCheck.bicep モジュールに依存します。
orchestration.bicep からの次の抜粋は、使用中の dependsOn を示しています。
@description('The API version of the Azure Resource you need to use to check the state of a property.')
param parAzResourceApiVersion string = '2022-01-01'
@description('The property of the resource that you need to check. This is a property inside the `properties` bag of the resource that's captured from a GET call to the Resource ID.')
param parAzResourcePropertyToCheck string = 'routingState'
@description('The value of the property of the resource that you need to check.')
param parAzResourceDesiredState string = 'Provisioned'
@description('The duration that the deployment script waits between check or polling requests to check the property and its state, if it is not in its desired state. The duration defaults to `30` seconds.')
param parWaitInSecondsBetweenIterations int = 30
module modVWANHub 'modules/vwanHub.bicep' = {
scope: rsg
name: 'deployVWANHub'
params: {
region: region
regionNamePrefix: regionNamePrefix
defaultTags: defaultTags
vwanHubCIDR: vwanHubCIDR
vwanName: modVWAN.outputs.vwanName
}
}
module modVWANHubRouterCheckerDeploymentScript 'modules/azResourceStateCheck.bicep' = {
scope: rsg
name: 'deployVWANHubRouterChecker'
params: {
parLocation: region
parAzResourceId: modVWANHub.outputs.outVwanVHubId
parAzResourceApiVersion: parAzResourceApiVersion
parAzResourcePropertyToCheck: parAzResourcePropertyToCheck
parAzResourceDesiredState: parAzResourceDesiredState
parMaxIterations: parMaxIterations
parWaitInSecondsBetweenIterations: parWaitInSecondsBetweenIterations
}
}
module modVWanVhubVnetConnections 'modules/vwanVhcs.bicep' = {
dependsOn: [
modVWANHubRouterCheckerDeploymentScript
]
scope: rsg
name: 'deployConnectVnetsToVWANVHub'
params: {
vnets: vnets
regionNamePrefix: regionNamePrefix
}
}
routingState プロパティの値が Provisioned になるまで、デプロイされた Virtual WAN ハブを使用する準備ができていないため、リソース チェックが必要です。 Virtual WAN ハブは、デプロイ エンジンがデプロイを続行できるように、デプロイの成功をResource Managerに報告します。 Virtual WAN ハブ ルーターが作成されたハブにプロビジョニングされた後、新しいVirtual WAN ハブが動作します。 このプロセスには約 15 分かかります。 この動作は、新しいVirtual WAN ハブの次のスクリーンショットで確認できます。 このスクリーンショットは、ハブの状態が Succeeded ですが、ルーティングの状態が Provisioning を示しています。
routingState値がProvisionedされる前に vwanvhcs.bicep モジュールをデプロイしようとすると、接続の作成が失敗し、デプロイ全体が失敗します。 ルーターがプロビジョニングされるまで、再デプロイの試行も失敗します。
次のスクリーンショットは、Virtual WAN ハブの routingState チェック中のデプロイ スクリプト ログの例を示しています。 ログには、 Provisioned以外の値を返すプロパティのチェックが繰り返し表示されます。
次のスクリーンショットは、値が Provisioned に変わることを示しています。
イテレーションの最大数後に値が Provisioned に変更されない場合、スクリプトは例外を生成し、スクリプト リソースのエラーがResource Managerされることを通知します。 Resource Managerデプロイ エンジンは失敗し、デプロイを停止します。例外は、トラブルシューティングを必要とするAzure リソースに問題があることを示しているためです。 詳細については、次の Invoke-AzResourceStateCheck.ps1 スクリプトを参照してください。
[CmdletBinding()]
param (
[string]
$azResourceResourceId,
[string]
$apiVersion = "2022-05-01",
[string]
$azResourcePropertyToCheck = "provisioningState",
[string]
$azResourceDesiredState = "Provisioned",
[int]
$waitInSecondsBetweenIterations = 30,
[int]
$maxIterations = 30
)
$totalTimeoutCalculation = $waitInSecondsBetweenIterations * $maxIterations
$azResourcePropertyExistenceCheck = Invoke-AzRestMethod -Method GET -Path "$($azResourceResourceId)?api-version=$($apiVersion)"
if ($azResourcePropertyExistenceCheck.StatusCode -ne "200") {
$DeploymentScriptOutputs["azResourcePropertyState"] = "Not Found"
throw "Unable to get Azure Resource - $($azResourceResourceId). Likely it doesn't exist. Status code: $($azResourcePropertyExistenceCheck.StatusCode) Error: $($azResourcePropertyExistenceCheck.Content)"
}
$azResourcePropertyStateResult = "Unknown"
$iterationCount = 0
do {
$azResourcePropertyStateGet = Invoke-AzRestMethod -Method GET -Path "$($azResourceResourceId)?api-version=$($apiVersion)"
$azResourcePropertyStateJsonConverted = $azResourcePropertyStateGet.Content | ConvertFrom-Json -Depth 10
$azResourcePropertyStateResult = $azResourcePropertyStateJsonConverted.properties.$($azResourcePropertyToCheck)
if ($azResourcePropertyStateResult -ne $azResourceDesiredState) {
Write-Host "Azure Resource Property ($($azResourcePropertyToCheck)) is not in $($azResourceDesiredState) state. Waiting $($waitInSecondsBetweenIterations) seconds before checking again. Iteration count: $($iterationCount)"
Start-Sleep -Seconds $waitInSecondsBetweenIterations
$iterationCount++
}
} while (
$azResourcePropertyStateResult -ne $azResourceDesiredState -and $iterationCount -ne $maxIterations
)
if ($azResourcePropertyStateResult -eq $azResourceDesiredState) {
Write-Host "Azure Resource Property ($($azResourcePropertyToCheck)) is now in $($azResourceDesiredState) state."
$DeploymentScriptOutputs["azResourcePropertyState"] = "$($azResourceDesiredState)"
}
if ($iterationCount -eq $maxIterations -and $azResourcePropertyStateResult -ne $azResourceDesiredState) {
$DeploymentScriptOutputs["azResourcePropertyState"] = "Azure Resource Property ($($azResourcePropertyToCheck)) is still not in desired state of $($azResourceDesiredState). Timeout reached of $($totalTimeoutCalculation) seconds."
throw "Azure Resource Property ($($azResourcePropertyToCheck)) is still not in $($azResourceDesiredState) state after $($totalTimeoutCalculation) seconds."
}
Contributors
Microsoft では、この記事を保持しています。 この記事を書いたのは、以下の寄稿者です。
主要著者:
- ジャック・トレーシー |シニア クラウド ソリューション アーキテクト
その他の共同作成者:
- ゲイリー・マクマホン |シニア クラウド ソリューション アーキテクト
公開されていない LinkedIn プロフィールを見るには、LinkedIn にサインインしてください。
次のステップ
- Azure/CAE-Bits リポジトリの例のファイル
- Bicep でデプロイ スクリプトを使う
- Learn モジュール: デプロイ スクリプトを使用して Bicep テンプレートと ARM テンプレートを拡張する
- 例外について知りたいこと
- Virtual WAN へ移行します
- Bicep のリソースの依存関係
- Bicep のドキュメント