Implantar recursos condicionalmente

Concluído

Você pode usar condições em seu código Bicep para implantar recursos somente quando restrições específicas estiverem em vigor.

Por exemplo, na sua empresa de brinquedos, você precisa implantar recursos em vários ambientes. Ao implantá-los em um ambiente de produção, você precisa garantir que a auditoria esteja habilitada para seus servidores lógicos do SQL do Azure. Mas, ao implantar recursos em ambientes de desenvolvimento, não convém habilitar a auditoria. Você vai querer usar um único modelo para implantar recursos em todos os seus ambientes.

Nessa unidade, você saberá como implantar recursos condicionalmente.

Usar condições básicas

Ao implantar um recurso no Bicep, você pode fornecer a palavra-chave if seguida por uma condição. A condição deve ser avaliada como um valor booliano (true ou false). Se o valor for true, o recurso será implantado. Se o valor for false, o recurso não será implantado.

É comum criar condições com base nos valores dos parâmetros que você fornece. Por exemplo, o seguinte código implanta uma conta de armazenamento somente quando o parâmetro deployStorageAccount é definido como true:

param deployStorageAccount bool

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

Observe que a palavra-chave if está na mesma linha que a definição de recurso.

Usar expressões como condições

O exemplo anterior era bem básico. O parâmetro deployStorageAccount era do tipo bool, portanto, fica claro se ele tem um valor de true ou false.

No Bicep, as condições também podem incluir expressões. No seguinte exemplo, o código implanta um recurso de auditoria do SQL somente quando o valor do parâmetro environmentName é igual a Production:

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

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

Geralmente, é uma boa ideia criar uma variável para a expressão que você está usando como uma condição. Dessa forma, o modelo é mais fácil de entender e de ler. Aqui está um exemplo:

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

var auditingEnabled = environmentName == 'Production'

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

Depender de recursos implantados condicionalmente

Quando você implanta recursos condicionalmente, às vezes precisa estar ciente de como o Bicep avalia as dependências entre eles.

Vamos continuar escrevendo um código Bicep para implantar as configurações de auditoria do SQL. O arquivo Bicep também precisa declarar um recurso de conta de armazenamento, conforme mostrado aqui:

@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@2023-05-01' = if (auditingEnabled) {
  name: auditStorageAccountName
  location: location
  sku: {
    name: storageAccountSkuName
  }
  kind: 'StorageV2'
}

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

Observe que a conta de armazenamento também tem uma condição. Isso significa que ele também não será implantado para ambientes de não produção. O recurso de configurações de auditoria do SQL agora pode se referir aos detalhes da conta de armazenamento:

resource auditingSettings 'Microsoft.Sql/servers/auditingSettings@2023-08-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 : ''
  }
}

Observe que esse código Bicep usa o operador de ponto de interrogação (?) dentro das propriedades storageEndpoint e storageAccountAccessKey. Quando o código Bicep é implantado em um ambiente de produção, as expressões são avaliadas como os detalhes da conta de armazenamento. Quando o código é implantado em um ambiente de não produção, as expressões são avaliadas como uma cadeia de caracteres vazia ('').

Você pode se perguntar por que esse código é necessário, porque auditingSettings e auditStorageAccount têm a mesma condição e, portanto, você nunca precisará implantar um recurso de configurações de auditoria do SQL sem uma conta de armazenamento. Embora isso seja verdadeiro, o Azure Resource Manager avalia as expressões de propriedade antes das condicionais nos recursos. Isso significa que, se o código Bicep não tiver essa expressão, a implantação irá falhar com um erro ResourceNotFound.

Observação

Você não pode definir dois recursos com o mesmo nome no mesmo arquivo Bicep e, em seguida, implantar condicionalmente apenas um deles. A implantação falhará, porque o Resource Manager interpreta isso como um conflito.

Se você tiver vários recursos, todos com a mesma condição para implantação, considere usar módulos Bicep. Você pode criar um módulo que implanta todos os recursos e, em seguida, colocar uma condição na declaração do módulo no seu arquivo Bicep principal.