Distribuire le risorse in modo condizionale

Completato

È possibile usare le condizioni nel codice Bicep per distribuire le risorse solo quando sono presenti vincoli specifici.

Si lavora, ad esempio, per un'azienda di giocattoli ed è necessario distribuire le risorse in diversi ambienti. Quando si esegue la distribuzione in un ambiente di produzione, è necessario assicurarsi che sia abilitato il controllo per i server logici Azure SQL. Quando tuttavia si esegue la distribuzione delle risorse negli ambienti di sviluppo, non si vuole abilitare il controllo. Si vuole usare un singolo modello per distribuire le risorse in tutti gli ambienti.

In questa unità si apprenderà come distribuire le risorse in modo condizionale.

Usare condizioni di base

Quando si distribuisce una risorsa in Bicep, è possibile specificare la parola chiave if seguita da una condizione. La condizione deve restituire un valore booleano (true o false). Se il valore è true, la risorsa viene distribuita. Se il valore è false, la risorsa non viene distribuita.

È prassi comune creare condizioni basate sui valori di parametri forniti. Il codice seguente consente ad esempio di distribuire un account di archiviazione solo quando il parametro deployStorageAccount è impostato su true:

param deployStorageAccount bool

resource storageAccount 'Microsoft.Storage/storageAccounts@2021-09-01' = if (deployStorageAccount) {
  name: 'teddybearstorage'
  location: resourceGroup().location
  kind: 'StorageV2'
  // ...
}

Si noti che la parola chiave if si trova nella stessa riga della definizione della risorsa.

Usare le espressioni nelle condizioni

L'esempio precedente è piuttosto semplice. Il parametro deployStorageAccount è di tipo bool, quindi è chiaro se il suo valore ètrue o false.

In Bicep le condizioni possono includere anche espressioni. Nell'esempio seguente il codice consente di distribuire una risorsa di controllo SQL solo quando il valore del parametro environmentName è uguale a Production:

@allowed([
  'Development'
  'Production'
])
param environmentName string

resource auditingSettings 'Microsoft.Sql/servers/auditingSettings@2021-11-01-preview' = if (environmentName == 'Production') {
  parent: server
  name: 'default'
  properties: {
  }
}

In genere è una buona idea creare una variabile per l'espressione che si usa come condizione. In questo modo, il modello sarà più facile da comprendere e da leggere. Ecco un esempio:

@allowed([
  'Development'
  'Production'
])
param environmentName string

var auditingEnabled = environmentName == 'Production'

resource auditingSettings 'Microsoft.Sql/servers/auditingSettings@2021-11-01-preview' = if (auditingEnabled) {
  parent: server
  name: 'default'
  properties: {
  }
}

Creare dipendenze dalle risorse distribuite in modo condizionale

Quando si distribuiscono le risorse in modo condizionale, può essere utile comprendere come Bicep valuta le dipendenze tra di esse.

Si scriverà ora codice Bicep per distribuire le impostazioni di controllo SQL. Il file Bicep deve anche dichiarare una risorsa account di archiviazione, come illustrato di seguito:

@allowed([
  'Development'
  'Production'
])
param environmentName string
param location string = resourceGroup().location
param auditStorageAccountName string = 'bearaudit${uniqueString(resourceGroup().id)}'

var auditingEnabled = environmentName == 'Production'
var storageAccountSkuName = 'Standard_LRS'

resource auditStorageAccount 'Microsoft.Storage/storageAccounts@2021-09-01' = if (auditingEnabled) {
  name: auditStorageAccountName
  location: location
  sku: {
    name: storageAccountSkuName
  }
  kind: 'StorageV2'
}

resource auditingSettings 'Microsoft.Sql/servers/auditingSettings@2021-11-01-preview' = if (auditingEnabled) {
  parent: server
  name: 'default'
  properties: {
  }
}

Si noti che anche l'account di archiviazione prevede una condizione. Ciò significa che anch'esso non verrà distribuito per gli ambienti non di produzione. La risorsa impostazioni di controllo SQL può ora fare riferimento ai dettagli dell'account di archiviazione:

resource auditingSettings 'Microsoft.Sql/servers/auditingSettings@2021-11-01-preview' = if (auditingEnabled) {
  parent: server
  name: 'default'
  properties: {
    state: 'Enabled'
    storageEndpoint: environmentName == 'Production' ? auditStorageAccount.properties.primaryEndpoints.blob : ''
    storageAccountAccessKey: environmentName == 'Production' ? listKeys(auditStorageAccount.id, auditStorageAccount.apiVersion).keys[0].value : ''
  }
}

Si noti che questo codice Bicep usa l'operatore punto interrogativo (?) nelle proprietà storageEndpoint e storageAccountAccessKey. Quando il codice Bicep viene distribuito in un ambiente di produzione, le espressioni restituiscono i dettagli dell'account di archiviazione. Quando il codice viene distribuito in un ambiente non di produzione, le espressioni restituiscono una stringa vuota ('').

Ci si potrebbe chiedere il motivo della necessità di questo codice, in quanto le proprietà auditingSettings e auditStorageAccount hanno entrambe la stessa condizione e quindi non sarà mai necessario distribuire una risorsa impostazioni di controllo SQL senza un account di archiviazione. Sebbene ciò sia vero, Azure Resource Manager valuta le espressioni di proprietà prima delle istruzioni condizionali delle risorse. Ciò significa che se il codice Bicep non ha questa espressione, la distribuzione avrà esito negativo con un ResourceNotFound errore.

Nota

Non è possibile definire due risorse con lo stesso nome nello stesso file Bicep e quindi distribuirne una sola delle due in modo condizionale. La distribuzione avrà esito negativo, in quanto Resource Manager interpreta questa situazione come un conflitto.

Se si hanno più risorse, tutte con la stessa condizione per la distribuzione, è consigliabile usare moduli Bicep. È possibile creare un modulo che distribuisce tutte le risorse, quindi inserire una condizione nella dichiarazione del modulo nel file Bicep principale.