Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
En este artículo se muestra cómo utilizar la sintaxis for
para recorrer en iteración los elementos de una colección. Esta funcionalidad se admite a partir de la versión 0.3.1. Puede usar bucles para definir varias copias de un recurso, un módulo, una variable, una propiedad o una salida. Use bucles para evitar la repetición de la sintaxis en el archivo de Bicep y para establecer de manera dinámica la cantidad de copias que se van a crear durante la implementación. Consulte Inicio rápido: Creación de varias instancias de recursos en Bicep para obtener un inicio rápido sobre cómo usar diferentes for
sintaxis para crear varias instancias de recursos en Bicep.
Para usar bucles para crear varios recursos o módulos, cada instancia debe tener un valor único para la name
propiedad . Puede usar el valor de índice o los valores únicos en matrices o colecciones para crear los nombres.
Recursos de aprendizaje
Para obtener instrucciones paso a paso sobre los bucles, consulte el módulo Crear archivos Bicep flexibles utilizando condiciones y bucles en Microsoft Learn.
Sintaxis de bucle
Los bucles se pueden declarar como se indica a continuación:
Mediante el uso de un índice de enteros. Esta opción funciona cuando el escenario es: "Quiero crear estas instancias". La función range crea una matriz de enteros que comienza en el índice de inicio y contiene el número de elementos especificados. En el bucle, puede utilizar el índice entero para modificar los valores. Para más información, consulte la sección Índice de enteros.
[for <index> in range(<startIndex>, <numberOfElements>): { ... }]
Usar elementos de una matriz: esta opción funciona cuando el escenario es "Quiero crear una instancia para cada elemento de una matriz". Dentro del bucle, puede usar el valor del elemento de matriz actual para modificar los valores. Para más información, consulte la sección Elementos de matriz.
[for <item> in <collection>: { ... }]
Uso de elementos en un objeto de diccionario: esta opción funciona cuando el escenario es "Quiero crear una instancia para cada elemento de un objeto". La función items convierte el objeto en una matriz. En el bucle, puede usar las propiedades del objeto para crear los valores. Para más información, consulte la sección Objeto de diccionario.
[for <item> in items(<object>): { ... }]
Usar el índice entero y los elementos de una matriz: esta opción funciona cuando el escenario es " Quiero crear una instancia para cada elemento de una matriz, pero también necesito el índice actual para crear otro valor". Para obtener más información, consulte Matriz de bucles e índice.
[for (<item>, <index>) in <collection>: { ... }]
Agregar una implementación condicional: esta opción funciona cuando el escenario es " Quiero crear varias instancias, pero solo quiero implementar cada instancia cuando se cumple una condición". Para obtener más información, consulte Bucle con condición.
[for <item> in <collection>: if(<condition>) { ... }]
Límites del bucle
El uso de bucles en Bicep tiene las limitaciones siguientes:
- Los bucles de Bicep solo funcionan con valores que se pueden determinar al principio de la implementación.
- Las iteraciones de bucle no pueden ser un número negativo ni superar las 800 iteraciones.
- Dado que un recurso no puede realizar un bucle con recursos secundarios anidados, cambie los recursos secundarios a recursos de nivel superior. Para obtener más información, consulte Iteración de un recurso secundario.
- Para recorrer en bucle varios niveles de propiedad, use la función lambda
map
.
Índice de enteros
Para obtener un ejemplo sencillo de uso de un índice, cree una variable que contenga una matriz de cadenas:
param itemCount int = 5
var stringArray = [for i in range(0, itemCount): 'item${(i + 1)}']
output arrayResult array = stringArray
La salida devuelve una matriz con los valores siguientes:
[
"item1",
"item2",
"item3",
"item4",
"item5"
]
En el ejemplo siguiente, se crea el número de cuentas de almacenamiento especificado en el parámetro storageCount
. Devuelve tres propiedades para cada cuenta de almacenamiento:
param ___location string = resourceGroup().___location
param storageCount int = 2
resource storageAcct 'Microsoft.Storage/storageAccounts@2023-05-01' = [for i in range(0, storageCount): {
name: '${i}storage${uniqueString(resourceGroup().id)}'
___location: ___location
sku: {
name: 'Standard_LRS'
}
kind: 'Storage'
}]
output storageInfo array = [for i in range(0, storageCount): {
id: storageAcct[i].id
blobEndpoint: storageAcct[i].properties.primaryEndpoints.blob
status: storageAcct[i].properties.statusOfPrimary
}]
Observe que el índice i
se usa para crear el nombre del recurso de la cuenta de almacenamiento.
En el ejemplo siguiente se implementa un módulo varias veces:
param ___location string = resourceGroup().___location
param storageCount int = 2
var baseName = 'store${uniqueString(resourceGroup().id)}'
module stgModule './storageAccount.bicep' = [for i in range(0, storageCount): {
name: '${i}deploy${baseName}'
params: {
storageName: '${i}${baseName}'
___location: ___location
}
}]
output storageAccountEndpoints array = [for i in range(0, storageCount): {
endpoint: stgModule[i].outputs.storageEndpoint
}]
Elementos de matriz
En el ejemplo siguiente, se crea una cuenta de almacenamiento para cada nombre proporcionado en el parámetro storageNames
. Tenga en cuenta que la propiedad name de cada instancia de recurso debe ser única:
param ___location string = resourceGroup().___location
param storageNames array = [
'contoso'
'fabrikam'
'coho'
]
resource storageAcct 'Microsoft.Storage/storageAccounts@2023-05-01' = [for name in storageNames: {
name: '${name}${uniqueString(resourceGroup().id)}'
___location: ___location
sku: {
name: 'Standard_LRS'
}
kind: 'Storage'
}]
En el ejemplo siguiente, se recorre en iteración una matriz a fin de definir una propiedad. Crea dos subredes dentro de una red virtual. Tenga en cuenta que los nombres de subred deben ser únicos:
param rgLocation string = resourceGroup().___location
var subnets = [
{
name: 'api'
subnetPrefix: '10.144.0.0/24'
}
{
name: 'worker'
subnetPrefix: '10.144.1.0/24'
}
]
resource vnet 'Microsoft.Network/virtualNetworks@2023-11-01' = {
name: 'vnet'
___location: rgLocation
properties: {
addressSpace: {
addressPrefixes: [
'10.144.0.0/20'
]
}
subnets: [for subnet in subnets: {
name: subnet.name
properties: {
addressPrefix: subnet.subnetPrefix
}
}]
}
}
Matriz e índice
En el ejemplo siguiente se usa el elemento de matriz y el valor de índice al definir la cuenta de almacenamiento:
param storageAccountNamePrefix string
var storageConfigurations = [
{
suffix: 'local'
sku: 'Standard_LRS'
}
{
suffix: 'geo'
sku: 'Standard_GRS'
}
]
resource storageAccountResources 'Microsoft.Storage/storageAccounts@2023-05-01' = [for (config, i) in storageConfigurations: {
name: '${storageAccountNamePrefix}${config.suffix}${i}'
___location: resourceGroup().___location
sku: {
name: config.sku
}
kind: 'StorageV2'
}]
En el ejemplo siguiente se usan los elementos de una matriz y un índice para generar información sobre los nuevos recursos:
param ___location string = resourceGroup().___location
param orgNames array = [
'Contoso'
'Fabrikam'
'Coho'
]
resource nsg 'Microsoft.Network/networkSecurityGroups@2023-11-01' = [for name in orgNames: {
name: 'nsg-${name}'
___location: ___location
}]
output deployedNSGs array = [for (name, i) in orgNames: {
orgName: name
nsgName: nsg[i].name
resourceId: nsg[i].id
}]
Objeto de diccionario
Para iterar sobre elementos de un objeto de diccionario, use la items
función, que convierte el objeto en una matriz. Utilice la propiedad value
para obtener propiedades de los objetos. Tenga en cuenta que los nombres de los recursos del grupo de seguridad de red deben ser únicos.
param nsgValues object = {
nsg1: {
name: 'nsg-westus1'
___location: 'westus'
}
nsg2: {
name: 'nsg-east1'
___location: 'eastus'
}
}
resource nsg 'Microsoft.Network/networkSecurityGroups@2023-11-01' = [for nsg in items(nsgValues): {
name: nsg.value.name
___location: nsg.value.___location
}]
Bucle con condición
En el caso de los recursos y módulos, puede agregar una expresión if
con la sintaxis de bucle para implementar condicionalmente la colección.
En el ejemplo siguiente, se muestra un bucle combinado con una instrucción de condición. En este ejemplo, se aplica una única condición a todas las instancias del módulo:
param ___location string = resourceGroup().___location
param storageCount int = 2
param createNewStorage bool = true
var baseName = 'store${uniqueString(resourceGroup().id)}'
module stgModule './storageAccount.bicep' = [for i in range(0, storageCount): if(createNewStorage) {
name: '${i}deploy${baseName}'
params: {
storageName: '${i}${baseName}'
___location: ___location
}
}]
En el ejemplo siguiente se muestra cómo aplicar una condición específica del elemento actual de la matriz:
resource parentResources 'Microsoft.Example/examples@2024-06-06' = [for parent in parents: if(parent.enabled) {
name: parent.name
properties: {
children: [for child in parent.children: {
name: child.name
setting: child.settingValue
}]
}
}]
Implementación por lotes
Los recursos de Azure se implementan en paralelo de forma predeterminada. Cuando se usa un bucle para crear varias instancias de un tipo de recurso, todas esas instancias se implementan al mismo tiempo. No se garantiza el orden en el que se crean. No hay un límite en el número de recursos implementados en paralelo que no sean el límite total de 800 recursos en el archivo de Bicep.
Es posible que no quiera actualizar todas las instancias de un tipo de recurso al mismo tiempo. Por ejemplo, al actualizar un entorno de producción, es posible que desee escalonar las actualizaciones para que solo un número determinado se actualice en cualquier momento. Puede especificar que un subconjunto de las instancias sea agrupado e implementado al mismo tiempo. Las demás instancias esperan a que se complete ese lote.
Para implementar en serie instancias de un recurso, agregue el batchSize
decorador. Establezca su valor en el número de instancias que se van a implementar a la vez. Se crea una dependencia durante las instancias anteriores del bucle, por lo que no inicia un lote hasta que se completa el lote anterior.
param ___location string = resourceGroup().___location
@batchSize(2)
resource storageAcct 'Microsoft.Storage/storageAccounts@2023-05-01' = [for i in range(0, 4): {
name: '${i}storage${uniqueString(resourceGroup().id)}'
___location: ___location
sku: {
name: 'Standard_LRS'
}
kind: 'Storage'
}]
Para una implementación secuencial, establezca el tamaño del lote en 1.
El decorador batchSize
está en el espacio de nombres sys. Si necesita diferenciar este decorador de otro elemento con el mismo nombre, ponga sys delante: @sys.batchSize(2)
Iteración para un recurso secundario
Para crear más de una instancia de un recurso secundario, ambos archivos de Bicep siguientes admiten esta tarea:
Recursos secundarios anidados
param ___location string = resourceGroup().___location
resource stg 'Microsoft.Storage/storageAccounts@2023-05-01' = {
name: 'examplestorage'
___location: ___location
kind: 'StorageV2'
sku: {
name: 'Standard_LRS'
}
resource service 'fileServices' = {
name: 'default'
resource share 'shares' = [for i in range(0, 3): {
name: 'exampleshare${i}'
}]
}
}
Recursos secundarios de nivel superior
resource stg 'Microsoft.Storage/storageAccounts@2023-05-01' = {
name: 'examplestorage'
___location: resourceGroup().___location
kind: 'StorageV2'
sku: {
name: 'Standard_LRS'
}
}
resource service 'Microsoft.Storage/storageAccounts/fileServices@2023-05-01' = {
name: 'default'
parent: stg
}
resource share 'Microsoft.Storage/storageAccounts/fileServices/shares@2023-05-01' = [for i in range(0, 3): {
name: 'exampleshare${i}'
parent: service
}]
Hacer referencia a colecciones de recursos o módulos
La función de plantilla de Azure Resource Manager (plantilla de ARM) references
devuelve una matriz de objetos que representan los estados en tiempo de ejecución de una colección de recursos. Dado que no hay una función explícita references
en Bicep y el uso de la colección simbólica se emplea directamente, Bicep lo traduce a una plantilla de ARM que utiliza la función de plantilla references
de ARM mientras se genera el código. Para la característica de traducción que usa la references
función para transformar colecciones simbólicas en plantillas de ARM, es necesario tener la CLI de Bicep versión 0.20.X o superior. Además, en el archivo bicepconfig.json, la configuración symbolicNameCodegen
debe presentarse y establecerse en true
.
Las salidas de los dos ejemplos en Índice enteros se pueden escribir como:
param ___location string = resourceGroup().___location
param storageCount int = 2
resource storageAcct 'Microsoft.Storage/storageAccounts@2023-05-01' = [for i in range(0, storageCount): {
name: '${i}storage${uniqueString(resourceGroup().id)}'
___location: ___location
sku: {
name: 'Standard_LRS'
}
kind: 'Storage'
}]
output storageInfo array = map(storageAcct, store => {
blobEndpoint: store.properties.primaryEndpoints
status: store.properties.statusOfPrimary
})
output storageAccountEndpoints array = map(storageAcct, store => store.properties.primaryEndpoints)
Este archivo de Bicep se transpila en la siguiente plantilla JSON de ARM que usa la references
función :
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"languageVersion": "1.10-experimental",
"contentVersion": "1.0.0.0",
"parameters": {
"___location": {
"type": "string",
"defaultValue": "[resourceGroup().___location]"
},
"storageCount": {
"type": "int",
"defaultValue": 2
}
},
"resources": {
"storageAcct": {
"copy": {
"name": "storageAcct",
"count": "[length(range(0, parameters('storageCount')))]"
},
"type": "Microsoft.Storage/storageAccounts",
"apiVersion": "2023-04-01",
"name": "[format('{0}storage{1}', range(0, parameters('storageCount'))[copyIndex()], uniqueString(resourceGroup().id))]",
"___location": "[parameters('___location')]",
"sku": {
"name": "Standard_LRS"
},
"kind": "Storage"
}
},
"outputs": {
"storageInfo": {
"type": "array",
"value": "[map(references('storageAcct', 'full'), lambda('store', createObject('blobEndpoint', lambdaVariables('store').properties.primaryEndpoints, 'status', lambdaVariables('store').properties.statusOfPrimary)))]"
},
"storageAccountEndpoints": {
"type": "array",
"value": "[map(references('storageAcct', 'full'), lambda('store', lambdaVariables('store').properties.primaryEndpoints))]"
}
}
}
Tenga en cuenta que en la plantilla JSON de ARM anterior, languageVersion
debe establecerse en 1.10-experimental
y el elemento de recurso es un objeto en lugar de una matriz.
Pasos siguientes
Para obtener información sobre cómo crear archivos de Bicep, consulte Estructura y sintaxis de archivos de Bicep.