Implementación condicional de recursos

Completado

Puede usar condiciones en el código de Bicep para implementar recursos solo cuando haya restricciones específicas.

Por ejemplo, en el caso de su empresa de juguetes, debe implementar recursos en varios entornos. Al implementarlos en un entorno de producción, debe asegurarse de que los servidores lógicos de Azure SQL tengan habilitada la auditoría. Sin embargo, si los recursos se implementan en entornos de desarrollo, no quiere habilitar la auditoría. Quiere usar una sola plantilla para implementar recursos en todos los entornos.

En esta unidad, aprenderá a implementar recursos de manera condicional.

Uso de condiciones básicas

Al implementar un recurso en Bicep, puede proporcionar la palabra clave if seguida de una condición. La condición debe resolverse en un valor booleano (true o false). Si el valor es true, se implementa el recurso. Si el valor es false, no se implementa el recurso.

Es habitual crear condiciones basadas en los valores de los parámetros que se proporcionen. Por ejemplo, el código siguiente implementa una cuenta de almacenamiento solo cuando el parámetro deployStorageAccount está establecido en true:

param deployStorageAccount bool

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

Observe que la palabra clave if está en la misma línea que la definición del recurso.

Uso de expresiones en condiciones

El ejemplo anterior era bastante básico. El parámetro deployStorageAccount era de tipo bool, por lo que está claro que tiene un valor de true o false.

En Bicep, las condiciones también pueden incluir expresiones. En el ejemplo siguiente, el código implementa un recurso de auditoría de SQL solo cuando el valor del parámetro environmentName es igual a Production:

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

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

Normalmente, es una buena idea crear una variable para la expresión que se usa como condición. De este modo, es más fácil comprender y leer la plantilla. Veamos un ejemplo:

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

var auditingEnabled = environmentName == 'Production'

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

Dependencia de los recursos implementados de manera condicional

Al implementar recursos de manera condicional, en ocasiones es necesario tener en cuenta cómo Bicep evalúa las dependencias entre ellos.

Vamos a seguir escribiendo código de Bicep para implementar la configuración de auditoría de SQL. El archivo de Bicep también debe declarar un recurso de cuenta de almacenamiento, como se muestra aquí:

@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@2024-05-01-preview' = if (auditingEnabled) {
  parent: server
  name: 'default'
  properties: {
  }
}

Observe que la cuenta de almacenamiento tiene también una condición. Esto significa que tampoco se implementará en entornos que no sean de producción. El recurso de configuración de auditoría de SQL ahora puede hacer referencia a los detalles de la cuenta de almacenamiento:

resource auditingSettings 'Microsoft.Sql/servers/auditingSettings@2024-05-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 este código de Bicep usa el operador de signo de interrogación (?) dentro de las propiedades storageEndpoint y storageAccountAccessKey. Cuando el código de Bicep se implementa en un entorno de producción, las expresiones se evalúan con los detalles de la cuenta de almacenamiento. Cuando el código se implementa en un entorno que no es de producción, las expresiones se evalúan como una cadena vacía ('').

Es posible que se pregunte por qué este código es necesario, ya que auditingSettings y auditStorageAccount tienen la misma condición, por lo que nunca tendría que implementar un recurso de configuración de auditoría de SQL sin una cuenta de almacenamiento. Aunque esto es cierto, Azure Resource Manager evalúa las expresiones de propiedad antes que las condiciones de los recursos. Esto significa que, si el código de Bicep no tiene esta expresión, se producirá un error ResourceNotFound en la implementación.

Nota:

No se pueden definir dos recursos con el mismo nombre en el mismo archivo de Bicep y, luego, implementar condicionalmente solo uno de ellos. La implementación producirá un error, ya que Resource Manager considera que hay un conflicto.

Si tiene varios recursos, todos con la misma condición para la implementación, considere el uso de módulos de Bicep. Puede crear un módulo que implemente todos los recursos y, luego, colocar una condición en la declaración del módulo en el archivo de Bicep principal.