Módulos de Bicep

Bicep permite organizar las implementaciones en módulos. Un módulo es simplemente un archivo de Bicep que se implementa desde otro archivo de Bicep. Con los módulos, mejora la legibilidad de los archivos de Bicep mediante la encapsulación de detalles complejos de la implementación. También puede reutilizar fácilmente módulos para distintas implementaciones.

A fin de compartir módulos con otros miembros de su organización, cree un registro privado. Los módulos del registro solo están disponibles para los usuarios con los permisos correctos.

Los módulos de Bicep se convierten en una sola plantilla de Azure Resource Manager con plantillas anidadas.

Microsoft Learn

Para más información sobre los módulos y para tener una guía práctica, consulte Creación de archivos Bicep que admiten composición mediante módulos en Microsoft Learn.

Sintaxis de definición

La sintaxis básica para definir un módulo es:

module <symbolic-name> '<path-to-file>' = {
  name: '<linked-deployment-name>'
  params: {
    <parameter-names-and-values>
  }
}

Por lo tanto, un ejemplo sencillo del mundo real tendría un aspecto similar a este:

module stgModule '../storageAccount.bicep' = {
  name: 'storageDeploy'
  params: {
    storagePrefix: 'examplestg1'
  }
}

Use el nombre simbólico para hacer referencia al módulo en otra parte del archivo de Bicep. Por ejemplo, puede usar el nombre simbólico para obtener la salida de un módulo. El nombre simbólico puede tener estos caracteres: a-z, A-Z, 0-9 y subrayado (_). No puede empezar con un número. Un módulo no puede tener el mismo nombre que un parámetro, una variable o un recurso.

La ruta de acceso puede ser un archivo local o un archivo en un registro. Para más información, consulte Ruta de acceso al módulo.

La propiedad name es obligatoria. Se convierte en el nombre del recurso de implementación anidado en la plantilla generada.

Si necesita especificar un ámbito distinto del ámbito del archivo principal, agregue la propiedad correspondiente. Para más información, consulte Establecimiento del ámbito del módulo.

// deploy to different scope
module <symbolic-name> '<path-to-file>' = {
  name: '<linked-deployment-name>'
  scope: <scope-object>
  params: {
    <parameter-names-and-values>
  }
}

A fin de implementar un módulo de manera condicional, agregue una expresión if. El uso es similar a la implementación condicional de un recurso.

// conditional deployment
module <symbolic-name> '<path-to-file>' = if (<condition-to-deploy>) {
  name: '<linked-deployment-name>'
  params: {
    <parameter-names-and-values>
  }
}

Para implementar más de una instancia de un módulo, agregue la expresión for. Puede usar el decorador batchSize para especificar si las instancias se implementan en serie o en paralelo. Para más información, consulte Bucles iterativos en Bicep.

// iterative deployment
@batchSize(int) // optional decorator for serial deployment
module <symbolic-name> '<path-to-file>' = [for <item> in <collection>: {
  name: '<linked-deployment-name>'
  params: {
    <parameter-names-and-values>
  }
}]

Al igual que los recursos, los módulos se implementan en paralelo a menos que dependan de otros módulos o recursos. Normalmente, no es necesario establecer dependencias, ya que se determinan implícitamente. Si necesita establecer una dependencia explícita, puede agregar dependsOn a la definición del módulo. Para más información sobre las dependencias, consulte Dependencias de recursos.

module <symbolic-name> '<path-to-file>' = {
  name: '<linked-deployment-name>'
  params: {
    <parameter-names-and-values>
  }
  dependsOn: [
    <symbolic-names-to-deploy-before-this-item>
  ]
}

Ruta de acceso al módulo

El archivo del módulo puede ser un archivo local o uno externo en un registro de módulo de Bicep. Ambas opciones se muestran a continuación.

Archivo local

Si el módulo es un archivo local, proporcione una ruta de acceso relativa a ese archivo. Todas las rutas de acceso de Bicep deben especificarse mediante el separador de directorios de barra diagonal (/), con el fin de garantizar una compilación coherente entre plataformas. El carácter de barra diagonal inversa de Windows (\) no se admite. Las rutas de acceso pueden contener espacios.

Por ejemplo, para implementar un archivo que está un nivel más arriba del archivo principal en el directorio, utilice:

module stgModule '../storageAccount.bicep' = {
  name: 'storageDeploy'
  params: {
    storagePrefix: 'examplestg1'
  }
}

Archivo en el registro

Si ha publicado un módulo en un registro, puede crear un vínculo a ese módulo. Proporcione el nombre del registro de contenedor de Azure y una ruta de acceso al módulo. Especifique la ruta de acceso al módulo con la sintaxis siguiente:

module <symbolic-name> 'br:<registry-name>.azurecr.io/<file-path>:<tag>' = {
  • br es el nombre del esquema de un registro de Bicep.
  • La ruta de acceso al archivo en Azure Container Registry se denomina repository. La ruta de acceso del archivo puede contener segmentos separados por el carácter /.
  • tag se usa para especificar una versión del módulo.

Por ejemplo:

module stgModule 'br:exampleregistry.azurecr.io/bicep/modules/storage:v1' = {
  name: 'storageDeploy'
  params: {
    storagePrefix: 'examplestg1'
  }
}

Cuando se hace referencia a un módulo en un registro, la extensión de Bicep en Visual Studio Code automáticamente llama a bicep restore para copiar el módulo externo en la caché local. El módulo externo tarda unos minutos en restaurarse. Si IntelliSense para el módulo no funciona de inmediato, espere a que se complete la restauración.

La ruta de acceso completa de un módulo en un registro puede ser larga. En lugar de proporcionar la ruta de acceso completa cada vez que desea usar el módulo, puede configurar alias en el archivo bicepconfig.json. Los alias facilitan la referencia al módulo. Por ejemplo, con un alias, puede acortar la ruta de acceso a:

module stgModule 'br/ContosoModules:storage:v1' = {
  name: 'storageDeploy'
  params: {
    storagePrefix: 'examplestg1'
  }
}

Parámetros

Los parámetros que proporciona en la definición del módulo coinciden con los parámetros del archivo de Bicep.

El ejemplo de Bicep siguiente tiene tres parámetros: storagePrefix, storageSKU y location. El parámetro storageSKU tiene un valor predeterminado, por lo que no es necesario proporcionar un valor para ese parámetro durante la implementación.

@minLength(3)
@maxLength(11)
param storagePrefix string

@allowed([
  'Standard_LRS'
  'Standard_GRS'
  'Standard_RAGRS'
  'Standard_ZRS'
  'Premium_LRS'
  'Premium_ZRS'
  'Standard_GZRS'
  'Standard_RAGZRS'
])
param storageSKU string = 'Standard_LRS'

param location string

var uniqueStorageName = '${storagePrefix}${uniqueString(resourceGroup().id)}'

resource stg 'Microsoft.Storage/storageAccounts@2021-04-01' = {
  name: uniqueStorageName
  location: location
  sku: {
    name: storageSKU
  }
  kind: 'StorageV2'
  properties: {
    supportsHttpsTrafficOnly: true
  }
}

output storageEndpoint object = stg.properties.primaryEndpoints

Para usar el ejemplo anterior como módulo, proporcione valores para esos parámetros.

targetScope = 'subscription'

@minLength(3)
@maxLength(11)
param namePrefix string

resource demoRG 'Microsoft.Resources/resourceGroups@2021-04-01' existing = {
  name: 'demogroup1'
}

module stgModule '../create-storage-account/main.bicep' = {
  name: 'storageDeploy'
  scope: demoRG
  params: {
    storagePrefix: namePrefix
    location: demoRG.location
  }
}

output storageEndpoint object = stgModule.outputs.storageEndpoint

Establecimiento del ámbito del módulo

Al declarar un módulo, puede establecer un ámbito para el módulo que sea diferente del ámbito del archivo de Bicep que lo contiene. Use la propiedad scope para establecer el ámbito del módulo. Cuando no se proporciona la propiedad scope, el módulo se implementa en el ámbito de destino del elemento primario.

En el archivo de Bicep siguiente se crea un grupo de recursos y una cuenta de almacenamiento en ese grupo. El archivo se implementa en una suscripción, pero el ámbito del módulo es el grupo de recursos nuevo.

// set the target scope for this file
targetScope = 'subscription'

@minLength(3)
@maxLength(11)
param namePrefix string

param location string = deployment().location

var resourceGroupName = '${namePrefix}rg'

resource newRG 'Microsoft.Resources/resourceGroups@2021-04-01' = {
  name: resourceGroupName
  location: location
}

module stgModule '../create-storage-account/main.bicep' = {
  name: 'storageDeploy'
  scope: newRG
  params: {
    storagePrefix: namePrefix
    location: location
  }
}

output storageEndpoint object = stgModule.outputs.storageEndpoint

En el ejemplo siguiente se implementan cuentas de almacenamiento en dos grupos de recursos diferentes. Ambos grupos de recursos ya deben existir.

targetScope = 'subscription'

resource firstRG 'Microsoft.Resources/resourceGroups@2021-04-01' existing = {
  name: 'demogroup1'
}

resource secondRG 'Microsoft.Resources/resourceGroups@2021-04-01' existing = {
  name: 'demogroup2'
}

module storage1 '../create-storage-account/main.bicep' = {
  name: 'westusdeploy'
  scope: firstRG
  params: {
    storagePrefix: 'stg1'
    location: 'westus'
  }
}

module storage2 '../create-storage-account/main.bicep' = {
  name: 'eastusdeploy'
  scope: secondRG
  params: {
    storagePrefix: 'stg2'
    location: 'eastus'
  }
}

Establezca la propiedad scope en un objeto de ámbito válido. Si el archivo Bicep implementa un grupo de recursos, una suscripción o un grupo de administración, puede establecer el ámbito de un módulo en el nombre simbólico de ese recurso. O bien, puede usar las funciones de ámbito para obtener un ámbito válido.

Estas funciones son las siguientes:

En el ejemplo siguiente se usa la función managementGroup para establecer el ámbito.

param managementGroupName string

module mgDeploy 'main.bicep' = {
  name: 'deployToMG'
  scope: managementGroup(managementGroupName)
}

Resultados

Puede obtener valores de un módulo y usarlos en el archivo de Bicep principal. Si desea obtener un valor de salida de un módulo, use la propiedad outputs en el objeto de módulo.

En el primer ejemplo se crea una cuenta de almacenamiento y se devuelven los puntos de conexión principales.

@minLength(3)
@maxLength(11)
param storagePrefix string

@allowed([
  'Standard_LRS'
  'Standard_GRS'
  'Standard_RAGRS'
  'Standard_ZRS'
  'Premium_LRS'
  'Premium_ZRS'
  'Standard_GZRS'
  'Standard_RAGZRS'
])
param storageSKU string = 'Standard_LRS'

param location string

var uniqueStorageName = '${storagePrefix}${uniqueString(resourceGroup().id)}'

resource stg 'Microsoft.Storage/storageAccounts@2021-04-01' = {
  name: uniqueStorageName
  location: location
  sku: {
    name: storageSKU
  }
  kind: 'StorageV2'
  properties: {
    supportsHttpsTrafficOnly: true
  }
}

output storageEndpoint object = stg.properties.primaryEndpoints

Cuando se usa como módulo, puede obtener ese valor de salida.

targetScope = 'subscription'

@minLength(3)
@maxLength(11)
param namePrefix string

resource demoRG 'Microsoft.Resources/resourceGroups@2021-04-01' existing = {
  name: 'demogroup1'
}

module stgModule '../create-storage-account/main.bicep' = {
  name: 'storageDeploy'
  scope: demoRG
  params: {
    storagePrefix: namePrefix
    location: demoRG.location
  }
}

output storageEndpoint object = stgModule.outputs.storageEndpoint

Pasos siguientes