控制迴圈執行和巢狀迴圈

已完成

藉由使用強大的複製迴圈功能,您就可以建立動態且彈性的範本。 請務必了解如何控制迴圈在建立資源時的執行方式,以及如何使用迴圈來設定資源屬性和巢狀迴圈。

在此單元中,您將了解如何控制複製迴圈的執行,以及如何在 Bicep 中使用資源屬性迴圈和巢狀迴圈。

注意

本單元中的命令僅用於示範概念。 請先不要執行命令。 您很快就會在此練習所學到的內容。

控制迴圈執行

依預設,Azure Resource Manager 會以平行方式但不具決定性的順序,從迴圈建立資源。 當您在先前的練習中建立迴圈時,會同時建立這兩個 Azure SQL 邏輯伺服器。 這有助於降低整體部署時間,因為迴圈內的所有資源都會一次部署完成。

不過,在某些情況下,您可能需要按順序而非平行方式部署資源,或以平行方式少量部署變更。 例如,如果實際執行環境中有許多 Azure App Service 應用程式,建議您一次只將變更部署至少量的應用程式,以防止更新同時重新啟動所有的應用程式。

您可以使用 @batchSize 裝飾項目,來控制複製迴圈在 Bicep 中的執行方式。 使用 for 關鍵字,將裝飾項目放在資源或模組宣告上。

讓我們看看範例 Bicep 定義中一組不含 @batchSize 裝飾項目的 App Service 應用程式:

resource appServiceApp 'Microsoft.Web/sites@2021-03-01' = [for i in range(1,3): {
  name: 'app${i}'
  // ...
}]

此迴圈中的所有資源將會以平行方式同時部署:

Diagram showing time on the horizontal axis, with app1, app2, and app3 stacked vertically to be deployed at the same time.

現在讓我們使用 2 的值套用 @batchSize 裝飾項目:

@batchSize(2)
resource appServiceApp 'Microsoft.Web/sites@2021-03-01' = [for i in range(1,3): {
  name: 'app${i}'
  // ...
}]

當您部署範本時,Bicep 會以兩個批次部署:

Diagram showing time on the horizontal axis, with app1 and app2 stacked to run as one batch, and app3 to run as a second batch.

注意

Bicep 會等候每個完整批次完成,再移至下一個批次。 在上述範例中,如果 app2app1 之前完成其部署,Bicep 會等到 app1 完成後,再開始部署 app3

您也可以將 @batchSize 設定為 1,以指示 Bicep 依序執行迴圈:

@batchSize(1)
resource appServiceApp 'Microsoft.Web/sites@2021-03-01' = [for i in range(1,3): {
  name: 'app${i}'
  // ...
}]

部署範本時,Bicep 會等候每個資源部署完成,然後再啟動下一個資源部署:

Diagram showing time on the horizontal axis, with app1, app2, and app3 being deployed sequentially.

使用迴圈搭配資源屬性

您可以使用迴圈來協助設定資源屬性。 例如,部署虛擬網路時,您需要指定其子網路。 子網路必須有兩項重要資訊:名稱和位址前置詞。 您可以使用具有物件陣列的參數,如此您就可以為每個環境指定不同的子網路:

param subnetNames array = [
  'api'
  'worker'
]

resource virtualNetwork 'Microsoft.Network/virtualNetworks@2021-08-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'
      }
    }]
  }
}

在此範例中,請注意,for 迴圈會出現在資源定義內 (在 subnets 屬性值周圍)。

巢狀迴圈

在某些情況下,您需要在另一個迴圈或巢狀迴圈內使用迴圈。 您可以使用 Bicep 來建立巢狀迴圈。

針對泰迪熊玩具公司,您需要在即將推出玩具的每個國家/地區或區域部署虛擬網路。 每個虛擬網路都需要不同的位址空間和兩個子網路。 讓我們從在迴圈中部署虛擬網路開始:

param locations array = [
  'westeurope'
  'eastus2'
  'eastasia'
]

var subnetCount = 2

resource virtualNetworks 'Microsoft.Network/virtualNetworks@2021-08-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@2021-08-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() 函數來建立兩個子網路。

當您部署範本時,會取得下列虛擬網路和子網路:

虛擬網路名稱 Location 位址首碼 子網路
vnet-westeurope westeurope 10.0.0.0/16 10.0.1.0/2410.0.2.0/24
vnet-eastus2 eastus2 10.1.0.0/16 10.1.1.0/2410.1.2.0/24
vnet-eastasia eastasia 10.2.0.0/16 10.2.1.0/2410.2.2.0/24