ループの実行を制御し、ループを入れ子にする
強力なコピー ループ機能を使用することにより、動的で柔軟なテンプレートを作成できます。 リソースを作成するときのループの実行方法を制御する方法と、ループを使用してリソースのプロパティと入れ子のループを設定する方法を理解することが重要です。
このユニットでは、コピー ループの実行を制御する方法と、Bicep でリソース プロパティのループと入れ子になったループを使用する方法について学習します。
Note
このユニットのコマンドは、概念を説明するために示されています。 コマンドはまだ実行しないでください。 ここで学習した内容をすぐに練習します。
ループの実行を制御する
既定では、Azure Resource Manager によるループからのリソースの作成は、並列に、非決定論的な順序で行われます。 前の演習でループを作成したときは、両方の Azure SQL 論理サーバーが同時に作成されました。 ループ内のすべてのリソースが一度にデプロイされるため、これは全体的なデプロイ時間を短縮するのに役立ちます。
ただし、場合によっては、ループ内でリソースを並列ではなく順番にデプロイしたり、小規模な変更のバッチをまとめて並列にデプロイすることが必要になります。 たとえば、運用環境に多数の Azure App Service アプリがある場合、更新によってすべてのアプリが同時に再起動されないよう、一度に少数のアプリにのみ変更をデプロイすることが必要になる場合があります。
@batchSize
デコレーターを使用することで、Bicep でのコピー ループの実行方法を制御できます。 for
キーワードを使用して、リソースまたはモジュールの宣言にデコレーターを設定します。
@batchSize
デコレーターを使用しない場合の、App Service アプリケーションのセットに対する Bicep の定義の例を見てみましょう。
resource appServiceApp 'Microsoft.Web/sites@2023-12-01' = [for i in range(1,3): {
name: 'app${i}'
// ...
}]
このループ内のすべてのリソースは同時に並列にデプロイされます。
次に、値を 2
にして @batchSize
デコレーターを適用します。
@batchSize(2)
resource appServiceApp 'Microsoft.Web/sites@2023-12-01' = [for i in range(1,3): {
name: 'app${i}'
// ...
}]
テンプレートをデプロイすると、2 つのバッチでデプロイされます。
Note
Bicep は、完全なバッチが完了するまで待ってから、次のバッチに進みます。 前の例では、app1 の前に app2 のデプロイが完了した場合、Bicep は app1 が完了するまで待ってから、app3 のデプロイを開始します。
また、@batchSize
を 1
に設定することで、ループを順番に実行するよう Bicep に指示することもできます。
@batchSize(1)
resource appServiceApp 'Microsoft.Web/sites@2023-12-01' = [for i in range(1,3): {
name: 'app${i}'
// ...
}]
そのテンプレートをデプロイすると、各リソースのデプロイが完了してから、次のデプロイが開始されます。
リソース プロパティでループを使用する
ループを使用して、リソースのプロパティを設定することができます。 たとえば、仮想ネットワークをデプロイする場合は、そのサブネットを指定する必要があります。 サブネットには、名前とアドレス プレフィックスという 2 つの重要な情報が必要です。 オブジェクトの配列でパラメーターを使用すると、環境ごとに異なるサブネットを指定できます。
param subnetNames array = [
'api'
'worker'
]
resource virtualNetwork 'Microsoft.Network/virtualNetworks@2024-01-01' = {
name: 'teddybear'
location: resourceGroup().location
properties: {
addressSpace: {
addressPrefixes: [
'10.0.0.0/16'
]
}
subnets: [for (subnetName, i) in subnetNames: {
name: subnetName
properties: {
addressPrefix: '10.0.${i}.0/24'
}
}]
}
}
この例では、リソース定義内で subnets
プロパティ値を囲むように for
ループが使用されていることに注意してください。
入れ子になったループ
シナリオによっては、別のループの内側でループを使用する必要があります ("入れ子になったループ")。 Bicep を使用して、入れ子になったループを作成できます。
テディ ベア玩具会社では、玩具が発売されるすべての国や地域に仮想ネットワークをデプロイする必要があります。 すべての仮想ネットワークには、異なるアドレス空間と 2 つのサブネットが必要です。 まず、ループ内で仮想ネットワークをデプロイします。
param locations array = [
'westeurope'
'eastus2'
'eastasia'
]
var subnetCount = 2
resource virtualNetworks 'Microsoft.Network/virtualNetworks@2024-01-01' = [for (location, i) in locations : {
name: 'vnet-${location}'
location: location
properties: {
addressSpace:{
addressPrefixes:[
'10.${i}.0.0/16'
]
}
}
}]
このループでは、各場所に仮想ネットワークがデプロイされ、ループ インデックスを使用して仮想ネットワークに addressPrefix
が設定されて、各仮想ネットワークで異なるアドレス プレフィックスを取得できるようになります。
入れ子になったループを使用して、各仮想ネットワーク内にサブネットをデプロイできます。
resource virtualNetworks 'Microsoft.Network/virtualNetworks@2024-01-01' = [for (location, i) in locations : {
name: 'vnet-${location}'
location: location
properties: {
addressSpace:{
addressPrefixes:[
'10.${i}.0.0/16'
]
}
subnets: [for j in range(1, subnetCount): {
name: 'subnet-${j}'
properties: {
addressPrefix: '10.${i}.${j}.0/24'
}
}]
}
}]
入れ子になったループでは、range()
関数を使用して 2 つのサブネットを作成します。
このテンプレートをデプロイすると、次の仮想ネットワークとサブネットが作成されます。
仮想ネットワーク名 | 場所 | アドレス プレフィックス | サブネット |
---|---|---|---|
vnet-westeurope |
westeurope |
10.0.0.0/16 |
10.0.1.0/24 、10.0.2.0/24 |
vnet-eastus2 |
eastus2 |
10.1.0.0/16 |
10.1.1.0/24 、10.1.2.0/24 |
vnet-eastasia |
eastasia |
10.2.0.0/16 |
10.2.1.0/24 、10.2.2.0/24 |