Execução de loops de controle e loops de aninhamento

Concluído

Usando o poderoso recurso de loops de cópia, você pode criar modelos dinâmicos e flexíveis. É importante entender como controlar a maneira como os loops são executados quando criam recursos e como usar loops para definir propriedades de recursos e aninhar loops.

Nesta unidade, você aprenderá como controlar a execução de loops de cópia e como usar loops de propriedade de recurso e loops aninhados no Bicep.

Nota

Os comandos nesta unidade são mostrados para ilustrar conceitos. Não execute os comandos ainda. Você vai praticar o que você aprende aqui em breve.

Execução de malha de controle

Por padrão, o Azure Resource Manager cria recursos a partir de loops em paralelo e em uma ordem não determinística. Quando você criou loops nos exercícios anteriores, ambos os servidores lógicos SQL do Azure foram criados ao mesmo tempo. Isso ajuda a reduzir o tempo geral de implantação, porque todos os recursos dentro do loop são implantados de uma só vez.

Em alguns casos, no entanto, talvez seja necessário implantar recursos em loops sequencialmente em vez de em paralelo, ou implantar pequenos lotes de alterações juntos em paralelo. Por exemplo, se você tiver muitos aplicativos do Serviço de Aplicativo do Azure em seu ambiente de produção, convém implantar alterações em apenas um pequeno número de cada vez para impedir que as atualizações reiniciem todas elas ao mesmo tempo.

Você pode controlar a maneira como seus loops de cópia são executados no Bicep usando o @batchSize decorador. Coloque o decorador na declaração de recurso ou módulo com a for palavra-chave.

Vejamos um exemplo de definição do Bicep para um conjunto de aplicativos do Serviço de Aplicativo sem o @batchSize decorador:

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

Todos os recursos deste ciclo serão implantados ao mesmo tempo, em paralelo:

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

Agora vamos aplicar o @batchSize decorador com um valor de 2:

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

Quando você implanta o modelo, o Bicep implanta em lotes de dois:

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.

Nota

O Bíceps espera que cada lote completo termine antes de passar para o próximo. No exemplo anterior, se app2 terminar sua implantação antes de app1, o Bicep aguardará até que app1 termine antes de começar a implantar app3.

Você também pode dizer ao Bicep para executar o loop sequencialmente definindo como @batchSize1:

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

Quando você implanta o modelo, o Bicep aguarda a conclusão de cada implantação de recurso antes de iniciar a próxima:

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

Usar loops com propriedades de recurso

Você pode usar loops para ajudar a definir as propriedades do recurso. Por exemplo, ao implantar uma rede virtual, você precisa especificar suas sub-redes. Uma sub-rede tem de ter duas informações importantes: um nome e um prefixo de endereço. Você pode usar um parâmetro com uma matriz de objetos para especificar sub-redes diferentes para cada ambiente:

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'
      }
    }]
  }
}

Neste exemplo, observe que o for loop aparece dentro da definição de recurso, em torno do valor da subnets propriedade.

Loops aninhados

Alguns cenários exigem que você use um loop dentro de outro loop ou um loop aninhado. Você pode criar loops aninhados usando o Bicep.

Para sua empresa de brinquedos de ursinho de pelúcia, você precisa implantar redes virtuais em todos os países/regiões onde o brinquedo será lançado. Cada rede virtual precisa de um espaço de endereçamento diferente e duas sub-redes. Vamos começar implantando as redes virtuais em um loop:

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'
      ]
    }
  }
}]

Esse loop implanta as redes virtuais para cada local e define o para a rede virtual usando o índice de loop para garantir que cada rede virtual obtenha um prefixo addressPrefix de endereço diferente.

Você pode usar um loop aninhado para implantar as sub-redes em cada rede virtual:

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'
      }
    }]
  }
}]

O loop aninhado usa a range() função para criar duas sub-redes.

Ao implantar o modelo, você obtém as seguintes redes virtuais e sub-redes:

Nome da rede virtual Localização Prefixo de endereço Sub-redes
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