Controllare l'esecuzione dei cicli e annidare i cicli

Completato

Usando la potente funzionalità dei cicli di copia, è possibile creare modelli dinamici e flessibili. È importante comprendere come controllare il modo in cui i cicli vengono eseguiti quando creano risorse e come usare i cicli per impostare le proprietà delle risorse e i cicli annidamento.

In questa unità si apprenderà come controllare l'esecuzione dei cicli di copia e come usare cicli di proprietà delle risorse e cicli annidati in Bicep.

Nota

I comandi riportati in questa unità vengono illustrati per spiegare i concetti. Non eseguire ancora i comandi. Presto sarà possibile provare quanto appreso.

Controllare l'esecuzione dei cicli

Per impostazione predefinita, Azure Resource Manager crea risorse da cicli in parallelo e in un ordine non deterministico. Quando sono stati creati i cicli negli esercizi precedenti, i due server logici Azure SQL sono stati creati contemporaneamente. Ciò consente di ridurre il tempo di distribuzione complessivo, in quanto tutte le risorse all'interno del ciclo vengono distribuite contemporaneamente.

In alcuni casi, tuttavia, può essere necessario distribuire le risorse nei cicli in sequenza anziché in parallelo oppure distribuire piccoli batch di modifiche contemporaneamente, in parallelo. Se, ad esempio, nell'ambiente di produzione sono presenti molte app del Servizio app di Azure, può essere necessario distribuire le modifiche solo a poche app per volta, per impedire che tutte vengano riavviate contemporaneamente a causa degli aggiornamenti.

È possibile controllare la modalità di esecuzione dei cicli di copia in Bicep usando l'elemento Decorator @batchSize. Inserire l'elemento Decorator nella dichiarazione di risorsa o di modulo con la parola chiave for.

Di seguito è illustrata una definizione Bicep di esempio per un set di applicazioni del servizio app senza l'elemento Decorator @batchSize:

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

Tutte le risorse in questo ciclo verranno distribuite contemporaneamente, in parallelo:

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

Applicare ora l'elemento Decorator @batchSize con il valore 2:

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

Quando si distribuisce il modello, Bicep esegue la distribuzione in batch di due:

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

Bicep attende il completamento di ogni batch prima di procedere con il successivo. Nell'esempio precedente, se la distribuzione di app2 viene completata prima di quella di app1, Bicep attende il completamento di app1 prima di iniziare a distribuire app3.

È anche possibile indicare a Bicep di eseguire il ciclo in sequenza impostando @batchSize su 1:

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

Quando si distribuisce il modello, Bicep attende il completamento della distribuzione di ogni risorsa prima di avviare quella successiva:

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

Usare i cicli con le proprietà delle risorse

È possibile usare i cicli per impostare le proprietà delle risorse. Quando ad esempio si distribuisce una rete virtuale, è necessario specificare le relative subnet. Una subnet deve avere due informazioni importanti: un nome e un prefisso di indirizzo. È possibile usare un parametro con una matrice di oggetti in modo da poter specificare subnet diverse per ogni 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'
      }
    }]
  }
}

In questo esempio il ciclo for si trova all'interno della definizione della risorsa, intorno al valore della proprietà subnets.

Cicli annidati

Alcuni scenari richiedono l'uso di un ciclo all'interno di un altro ciclo, ovvero un ciclo annidato. È possibile creare cicli annidati con Bicep.

Per l'azienda di giocattoli che produce l'orsacchiotto è necessario distribuire reti virtuali in ogni paese/area geografica in cui il giocattolo verrà lanciato. Ogni rete virtuale richiede uno spazio indirizzi diverso e due subnet. Distribuire prima di tutto le reti virtuali in un ciclo:

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

Questo ciclo distribuisce le reti virtuali per ogni località e imposta l'oggetto addressPrefix per la rete virtuale usando l'indice del ciclo per fare in modo che ogni rete virtuale ottenga un prefisso di indirizzo diverso.

È possibile usare un ciclo annidato per distribuire le subnet all'interno di ogni rete virtuale:

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

Il ciclo annidato usa la funzione range() per creare due subnet.

Quando si distribuisce il modello, si ottengono le reti virtuali e le subnet seguenti:

Nome della rete virtuale Ubicazione Prefisso indirizzo Subnet
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