Adición de parámetros y salidas a los módulos
Cada módulo que cree debe tener un propósito claro. Piense en un módulo como si se tratara de un contrato. Acepta un conjunto de parámetros, crea un conjunto de recursos y puede proporcionar algunas salidas de vuelta a la plantilla principal. El que use el módulo no debe preocuparse de cómo funciona, simplemente debe hacer lo que se espera de él.
Al planear un módulo, tenga en cuenta lo siguiente:
- Qué necesita saber para poder cumplir el propósito del módulo.
- Qué espera proporcionar cualquiera que utilice el módulo.
- A qué espera acceder en forma de salidas cualquiera que utilice el módulo.
Parámetros del módulo
Piense en los parámetros que acepta el módulo y si cada parámetro debe ser opcional o obligatorio.
Al crear parámetros para plantillas, es una buena práctica agregar parámetros predeterminados donde pueda. En los módulos, no siempre es tan importante agregar parámetros predeterminados porque el módulo lo usará una plantilla principal que podría usar sus propios parámetros predeterminados. Si tiene parámetros similares en ambos archivos, ambos con valores predeterminados, puede ser difícil para los usuarios de la plantilla averiguar qué valor predeterminado se aplicará y aplicar la coherencia. A menudo es mejor dejar el valor predeterminado en la plantilla principal y quitarlo del módulo.
También debe pensar en cómo administrar los parámetros que controlan las SKU de los recursos y otras opciones de configuración importantes. Al crear una plantilla de Bicep independiente, es habitual insertar reglas de negocio en la plantilla. Por ejemplo: Cuando implemento un entorno de producción, la cuenta de almacenamiento debe usar el nivel GRS. Pero a veces los módulos generan otras inquietudes.
Si va a crear un módulo que debe ser reutilizable y flexible, recuerde que las reglas de negocio de cada plantilla primaria pueden ser diferentes, por lo que es posible que no tenga mucho sentido insertar reglas de negocio en módulos genéricos. Considere la posibilidad de definir las reglas de negocio en la plantilla primaria y, después, pasar la configuración del módulo de forma explícita mediante parámetros.
Sin embargo, si crea un módulo diseñado para facilitarle a su propia organización la implementación de recursos que se ajusten a sus necesidades específicas, tiene sentido incluir reglas de negocio que simplifiquen las plantillas principales.
Independientemente de los parámetros que incluya en el módulo, asegúrese de agregar una descripción significativa mediante el atributo @description
:
@description('The name of the storage account to deploy.')
param storageAccountName string
Condiciones de uso
Uno de los objetivos de implementar una infraestructura con código como Bicep es evitar el trabajo duplicado, o incluso crear varias plantillas para el mismo propósito u otro similar. Las características de Bicep ofrecen un eficaz cuadro de herramientas para crear módulos reutilizables que funcionen en diversas situaciones. Puede combinar características como módulos, expresiones, valores de parámetros predeterminados y condiciones para crear código reutilizable que le proporciona la flexibilidad que necesita.
Imagine que va a crear un módulo que implementa una cuenta de Azure Cosmos DB. Cuando se implementa en el entorno de producción, debe configurar la cuenta para enviar sus registros a un área de trabajo de Log Analytics. Para configurar los registros que se enviarán a Log Analytics, definirá un recurso diagnosticSettings.
Podría lograr los requisitos si agrega una condición a la definición del recurso y hace que el parámetro de identificador del área de trabajo sea opcional mediante la adición de un valor predeterminado:
param logAnalyticsWorkspaceId string = ''
resource cosmosDBAccount 'Microsoft.DocumentDB/databaseAccounts@2022-08-15' = {
// ...
}
resource cosmosDBAccountDiagnostics 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = if (logAnalyticsWorkspaceId != '') {
scope: cosmosDBAccount
name: 'route-logs-to-log-analytics'
properties: {
workspaceId: logAnalyticsWorkspaceId
logs: [
{
category: 'DataPlaneRequests'
enabled: true
}
]
}
}
Al incluir este módulo en una plantilla de Bicep, puede configurarlo fácilmente para enviar los registros de la cuenta de Azure Cosmos DB a Log Analytics estableciendo un identificador de área de trabajo. O bien, si no necesita registros para el entorno que va a implementar, omita el parámetro. Tiene un valor predeterminado. El módulo encapsula la lógica necesaria para hacer lo correcto para sus requisitos.
Sugerencia
Recuerde comprobar que la plantilla sea válida para los dos escenarios, cuando la instrucción if
se evalúe como true
o false
.
Salidas del módulo
Los módulos pueden definir salidas. Es una buena idea crear una salida para la información que puede que tenga que usar la plantilla principal. Por ejemplo, si el módulo define una cuenta de almacenamiento, considere la posibilidad de crear una salida para el nombre de la cuenta de almacenamiento para que la plantilla principal pueda acceder a ella.
Advertencia
No use salidas para los valores secretos. Las salidas se registran como parte del historial de implementación, por lo que no son adecuadas para los valores seguros. En su lugar, puede considerar una de las siguientes opciones:
- Use una salida para proporcionar el nombre del recurso. A continuación, la plantilla principal puede crear un recurso
existing
con ese nombre y buscar el valor seguro dinámicamente. - Escriba el valor en un secreto de Azure Key Vault. Haga que la plantilla principal lea el secreto del almacén cuando lo necesite.
Una plantilla principal puede usar salidas de módulo en variables, puede usar propiedades para otras definiciones de recursos o puede exponer variables y propiedades como salidas propiamente dichas. Al exponer y usar salidas en los archivos de Bicep, puede crear conjuntos reutilizables de módulos de Bicep que se pueden compartir con el equipo y reutilizar en varias implementaciones. También es una buena práctica agregar una descripción significativa a las salidas mediante el atributo @description
:
@description('The fully qualified Azure resource ID of the blob container within the storage account.')
output blobContainerResourceId string = storageAccount::blobService::container.id
Sugerencia
También puede usar servicios dedicados para almacenar, administrar y acceder a la configuración que crea la plantilla de Bicep. Key Vault está diseñado para almacenar valores seguros. Azure App Configuration está diseñado para almacenar otros valores (no seguros).
Encadenar módulos juntos
Es habitual crear un archivo de Bicep principal que componga varios módulos juntos. Por ejemplo, imagine que va a crear una nueva plantilla de Bicep para implementar máquinas virtuales que usan redes virtuales dedicadas. Puede crear un módulo para definir una red virtual. A continuación, puede tomar el identificador de recursos de subred de la red virtual como salida de ese módulo y usarlo como entrada en el módulo de máquina virtual:
@description('Username for the virtual machine.')
param adminUsername string
@description('Password for the virtual machine.')
@minLength(12)
@secure()
param adminPassword string
module virtualNetwork 'modules/vnet.bicep' = {
name: 'virtual-network'
}
module virtualMachine 'modules/vm.bicep' = {
name: 'virtual-machine'
params: {
adminUsername: adminUsername
adminPassword: adminPassword
subnetResourceId: virtualNetwork.outputs.subnetResourceId
}
}
En este ejemplo, se usan nombres simbólicos para la referencia entre los módulos. Esto ayuda a Bicep a comprender automáticamente las relaciones entre los módulos.
Dado que Bicep entiende que hay una dependencia, implementa los módulos en secuencia:
- Bicep implementa todo en el módulo
virtualNetwork
. - Si la implementación se realiza correctamente, Bicep accede al valor de salida
subnetResourceId
y lo pasa al módulovirtualMachine
como parámetro. - Bicep implementa todo en el módulo
virtualMachine
.
Nota:
Cuando depende de un módulo, Bicep espera a que finalice toda la implementación del módulo. Es importante recordar esto al planear los módulos. Si crea un módulo que define un recurso que tarda mucho tiempo en implementarse, cualquier otro recurso que dependa de ese módulo esperará a que finalice la implementación de todo el módulo.