Implementación de varios recursos mediante bucles

Completado

Con frecuencia, tendrá que implementar varios recursos que sean muy similares. Si agrega bucles a los archivos de Bicep, puede evitar tener que repetir definiciones de recursos. En su lugar, puede establecer dinámicamente el número de instancias de un recurso que quiere implementar. Incluso puede personalizar las propiedades de cada instancia.

En su empresa de juguetes, debe implementar la infraestructura de back-end, lo que incluye algunos servidores lógicos de Azure SQL, para respaldar el lanzamiento del nuevo osito de peluche inteligente. En cada país o región donde el juguete va a estar disponible, debe implementar un servidor lógico dedicado para cumplir las leyes de protección de datos de cada país o región.

Además de sus ubicaciones, todos los servidores lógicos se configurarán de la misma manera. Para implementar los servidores lógicos, quiere usar código de Bicep, y un parámetro debe permitirle especificar las regiones en las que se deben implementar.

En esta unidad, aprenderá a implementar varias instancias de recursos mediante bucles de copia.

Nota:

Los comandos de esta unidad se muestran para ilustrar conceptos. No los ejecute todavía. Pronto va a practicar lo que aprenderá aquí.

Uso de bucles de copia

Al definir un recurso o un módulo en una plantilla de Bicep, puede usar la palabra clave for para crear un bucle. Coloque la palabra clave for en la declaración de recursos y, luego, especifique cómo quiere que Bicep identifique cada elemento del bucle. Normalmente, se recorre en bucle una matriz de objetos para crear varias instancias de un recurso. En el ejemplo siguiente se implementan varias cuentas de almacenamiento y sus nombres se especifican como valores de parámetro:

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

En este ejemplo, el bucle recorre en iteración cada elemento de la matriz storageAccountNames. Cada vez que Bicep recorre el bucle, coloca el valor actual en una variable especial denominada storageAccountName y se usa como valor de la propiedad name. Tenga en cuenta que en Bicep es necesario colocar un corchete de apertura ([) delante de la palabra clave for y un corchete de cierre (]) después de la definición del recurso.

Si ha implementado este archivo de Bicep, verá que se crean tres cuentas de almacenamiento, cuyos nombres se especifican mediante los elementos correspondientes de la matriz storageAccountNames.

Bucle basado en un recuento

En ocasiones, puede ser necesario un bucle para crear un número concreto de recursos y no usar una matriz como origen. Bicep proporciona la función range(), que crea una matriz de números. Por ejemplo, si necesita crear cuatro cuentas de almacenamiento, con los nombres de sa1 a sa4, podría usar una definición de recurso como esta:

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

Al usar la función range(), especifique su valor inicial y el número de valores que quiere crear. Por ejemplo, si quisiera crear cuentas de almacenamiento con los nombres sa0, sa1 y sa2, tendría que usar la función range(0,3).

Nota:

Cuando se usa la función range(), se proporcionan dos argumentos. El primero especifica el valor inicial y el segundo indica a Bicep el número de valores deseados. Por ejemplo, si usa range(3,4), Bicep devuelve los valores 3, 4, 5 y 6. Asegúrese de solicitar el número correcto de valores, especialmente cuando use un valor inicial de 0.

Acceso al índice de iteración

Con Bicep, puede recorrer en iteración las matrices y recuperar el índice del elemento actual de la matriz. Por ejemplo, supongamos que quiere crear un servidor lógico en cada ubicación especificada por una matriz y quiere que los nombres de los servidores sean sqlserver-1, sqlserver-2, etc. Esto se puede conseguir mediante el código de Bicep siguiente:

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

Observe que la propiedad name incluye la expresión i+1. El primer valor de la variable de índice i es cero, por lo que debe agregarle +1 si quiere que los nombres de servidor comiencen por 1.

Sugerencia

En este ejemplo, hemos denominado a la variable de índice i. Esta es la convención estándar de Bicep. Sin embargo, puede usar el nombre que prefiera.

Filtrado de elementos con bucles

En algunas situaciones, es posible que quiera implementar recursos mediante bucles de copia combinados con condiciones. Para ello, combine las palabras clave if y for.

En el ejemplo siguiente, el código usa un parámetro de matriz para definir un conjunto de servidores lógicos. Se usa una condición con el bucle de copia para implementar los servidores solo cuando la propiedad environmentName del objeto de bucle sea igual 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
  }
}]

Si ha implementado el ejemplo anterior, verá dos servidores lógicos, sqlserver-we y sqlserver-eas, pero no sqlserver-eus2, porque la propiedad environmentName de ese objeto no coincide con Production.