Distribuire più risorse usando i cicli

Completato

Spesso è necessario distribuire più risorse molto simili tra loro. Aggiungendo cicli ai file Bicep, è possibile evitare di ripetere le definizioni delle risorse. È invece possibile impostare dinamicamente il numero di istanze di una risorsa da distribuire. È anche possibile personalizzare le proprietà per ogni istanza.

Per l'azienda di giocattoli, è necessario distribuire l'infrastruttura back-end, inclusi alcuni server logici di Azure SQL, per supportare il lancio del nuovo orsacchiotto intelligente. È necessario distribuire un server logico dedicato in ogni paese/area geografica in cui il giocattolo sarà disponibile, così da garantire la conformità alle leggi sulla protezione dei dati di ogni paese/area geografica.

A parte le diverse località, tutti i server logici verranno configurati nello stesso modo. Si vuole usare il codice Bicep per distribuire i server logici e un parametro deve consentire di specificare le aree in cui distribuire tali server.

In questa unità si apprenderà come distribuire più istanze delle risorse usando cicli di copia.

Nota

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

Usare cicli di copia

Quando si definisce una risorsa o un modulo in un modello Bicep, è possibile usare la parola chiave for per creare un ciclo. Inserire la parola chiave for nella dichiarazione della risorsa e quindi specificare in che modo Bicep deve identificare ogni elemento nel ciclo. In genere si esegue un ciclo su una matrice di oggetti per creare più istanze di una risorsa. L'esempio seguente consente di distribuire più account di archiviazione, i cui nomi vengono specificati come valori di parametro:

param storageAccountNames array = [
  'saauditus'
  'saauditeurope'
  'saauditapac'
]

resource storageAccountResources 'Microsoft.Storage/storageAccounts@2023-05-01' = [for storageAccountName in storageAccountNames: {
  name: storageAccountName
  location: resourceGroup().location
  kind: 'StorageV2'
  sku: {
    name: 'Standard_LRS'
  }
}]

In questo esempio il ciclo scorre ogni elemento nella matrice storageAccountNames. Ogni volta che Bicep esegue il ciclo, inserisce il valore corrente in una variabile speciale denominata storageAccountName che viene usata come valore della proprietà name. Si noti che Bicep richiede l'inserimento di un carattere parentesi quadra di apertura ([) prima della parola chiave for e un carattere parentesi quadra di chiusura (]) dopo la definizione della risorsa.

Se si è distribuito questo file Bicep, sono stati creati tre account di archiviazione, con i nomi specificati dagli elementi corrispondenti nella matrice storageAccountNames.

Eseguire un ciclo basato su un conteggio

A volte può essere necessario eseguire un ciclo per creare un numero specifico di risorse e non usare una matrice come origine. Bicep fornisce la funzione range(), che crea una matrice di numeri. Se, ad esempio, è necessario creare quattro account di archiviazione, da sa1 a sa4, è possibile usare una definizione di risorsa simile alla seguente:

resource storageAccountResources 'Microsoft.Storage/storageAccounts@2023-05-01' = [for i in range(1,4): {
  name: 'sa${i}'
  location: resourceGroup().location
  kind: 'StorageV2'
  sku: {
    name: 'Standard_LRS'
  }
}]

Quando si usa la funzione range(), è necessario specificare il valore iniziale e il numero di valori da creare. Per creare, ad esempio, account di archiviazione con i nomi sa0, sa1 e sa2, usare la funzione range(0,3).

Nota

Quando si usa la funzione range(), è necessario fornire due argomenti. Il primo specifica il valore iniziale e il secondo indica a Bicep il numero di valori desiderato. Se, ad esempio, si usa range(3,4), Bicep restituisce i valori 3, 4, 5 e 6. Assicurarsi di richiedere il numero di valori appropriato, in particolare quando si usa un valore iniziale pari a 0.

Accedere all'indice di iterazione

Con Bicep è possibile scorrere le matrici e recuperare l'indice dell'elemento corrente nella matrice. Si supponga, ad esempio, di voler creare un server logico in ogni località specificata da una matrice e di voler usare per i server i nomi sqlserver-1, sqlserver-2 e così via. A tale scopo, è possibile usare il codice Bicep seguente:

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

resource sqlServers 'Microsoft.Sql/servers@2024-05-01-preview' = [for (location, i) in locations: {
  name: 'sqlserver-${i+1}'
  location: location
  properties: {
    administratorLogin: administratorLogin
    administratorLoginPassword: administratorLoginPassword
  }
}]

Si noti che la proprietà name include l'espressione i+1. Il primo valore della variabile di indice i è zero, quindi è necessario aggiungere +1 se si vuole che i nomi dei server inizino con 1.

Suggerimento

In questo esempio la variabile di indice è stata denominata i. Si tratta della convenzione standard in Bicep. È tuttavia possibile usare il nome desiderato.

Filtrare gli elementi con i cicli

In alcune situazioni può essere necessario distribuire le risorse usando cicli di copia combinati con condizioni. A tale scopo, è possibile combinare le parole chiave if e for.

Nell'esempio seguente il codice usa un parametro array per definire un set di server logici. Viene usata una condizione con il ciclo di copia per distribuire i server solo quando la proprietà environmentName dell'oggetto ciclo è uguale a Production:

param sqlServerDetails array = [
  {
    name: 'sqlserver-we'
    location: 'westeurope'
    environmentName: 'Production'
  }
  {
    name: 'sqlserver-eus2'
    location: 'eastus2'
    environmentName: 'Development'
  }
  {
    name: 'sqlserver-eas'
    location: 'eastasia'
    environmentName: 'Production'
  }
]

resource sqlServers 'Microsoft.Sql/servers@2024-05-01-preview' = [for sqlServer in sqlServerDetails: if (sqlServer.environmentName == 'Production') {
  name: sqlServer.name
  location: sqlServer.location
  properties: {
    administratorLogin: administratorLogin
    administratorLoginPassword: administratorLoginPassword
  }
  tags: {
    environment: sqlServer.environmentName
  }
}]

Se si è distribuito l'esempio precedente, vengono visualizzati due server logici, sqlserver-we e sqlserver-eas, ma non sqlserver-eus2, perché la proprietà environmentName di tale oggetto non corrisponde a Production.