Módulos bíceps
O Bicep permite organizar implantações em módulos. Um módulo é um arquivo Bicep (ou um modelo JSON do Azure Resource Manager) que é implantado a partir de outro arquivo Bicep. Com os módulos, você melhora a legibilidade de seus arquivos Bicep encapsulando detalhes complexos de sua implantação. Você também pode facilmente reutilizar módulos para diferentes implantações.
Para compartilhar módulos com outras pessoas em sua organização, crie uma especificação de modelo ou um registro privado. As especificações e módulos do modelo no registro só estão disponíveis para usuários com as permissões corretas.
Gorjeta
A escolha entre o registro do módulo e as especificações do modelo é principalmente uma questão de preferência. Há algumas coisas a considerar quando você escolhe entre os dois:
- O registro do módulo só é suportado pelo Bicep. Se você ainda não estiver usando o Bicep, use as especificações do modelo.
- O conteúdo no registro do módulo Bicep só pode ser implantado a partir de outro arquivo Bicep. As especificações de modelo podem ser implantadas diretamente da API, do Azure PowerShell, da CLI do Azure e do portal do Azure. Você pode até usar
UiFormDefinition
para personalizar a experiência de implantação do portal. - O Bicep tem alguns recursos limitados para incorporar outros artefatos do projeto (incluindo arquivos não-Bicep e não-ARM-template. Por exemplo, scripts do PowerShell, scripts da CLI e outros binários) usando as
loadTextContent
funções eloadFileAsBase64
. As especificações do modelo não podem empacotar esses artefatos.
Os módulos Bicep são convertidos em um único modelo do Azure Resource Manager com modelos aninhados. Para obter mais informações sobre como o Bicep resolve arquivos de configuração e como o Bicep mescla o arquivo de configuração definido pelo usuário com o arquivo de configuração padrão, consulte Processo de resolução do arquivo de configuração e Processo de mesclagem do arquivo de configuração.
Recursos de formação
Se você preferir aprender sobre módulos por meio de orientação passo a passo, consulte Criar arquivos Bicep composáveis usando módulos.
Definir módulos
A sintaxe básica para definir um módulo é:
@<decorator>(<argument>)
module <symbolic-name> '<path-to-file>' = {
name: '<linked-deployment-name>'
params: {
<parameter-names-and-values>
}
}
Assim, um exemplo simples e real seria parecido com:
module stgModule '../storageAccount.bicep' = {
name: 'storageDeploy'
params: {
storagePrefix: 'examplestg1'
}
}
Você também pode usar um modelo JSON ARM como um módulo:
module stgModule '../storageAccount.json' = {
name: 'storageDeploy'
params: {
storagePrefix: 'examplestg1'
}
}
Use o nome simbólico para fazer referência ao módulo em outra parte do arquivo Bicep. Por exemplo, você pode usar o nome simbólico para obter a saída de um módulo. O nome simbólico pode conter a-z, A-Z, 0-9 e sublinhado (_
). O nome não pode começar com um número. Um módulo não pode ter o mesmo nome que um parâmetro, variável ou recurso.
O caminho pode ser um arquivo local ou um arquivo em um registro. O arquivo local pode ser um arquivo Bicep ou um modelo JSON ARM. Para obter mais informações, consulte Caminho para o módulo.
A propriedade name é obrigatória. Ele se torna o nome do recurso de implantação aninhado no modelo gerado.
Se um módulo com um nome estático for implantado simultaneamente no mesmo escopo, há a possibilidade de uma implantação interferir na saída da outra implantação. Por exemplo, se dois arquivos Bicep usarem o mesmo módulo com o mesmo nome estático (examplemodule
) e direcionados para o mesmo grupo de recursos, uma implantação poderá mostrar a saída errada. Se você estiver preocupado com implantações simultâneas para o mesmo escopo, dê um nome exclusivo ao módulo.
O exemplo a seguir concatena o nome da implantação com o nome do módulo. Se você fornecer um nome exclusivo para a implantação, o nome do módulo também será exclusivo.
module stgModule 'storageAccount.bicep' = {
name: '${deployment().name}-storageDeploy'
scope: resourceGroup('demoRG')
}
Se você precisar especificar um escopo diferente do escopo do arquivo principal, adicione a propriedade scope. Para obter mais informações, consulte Definir escopo do módulo.
// deploy to different scope
module <symbolic-name> '<path-to-file>' = {
name: '<linked-deployment-name>'
scope: <scope-object>
params: {
<parameter-names-and-values>
}
}
Para implantar condicionalmente um módulo, adicione uma if
expressão. O uso é semelhante à implantação condicional de um recurso.
// conditional deployment
module <symbolic-name> '<path-to-file>' = if (<condition-to-deploy>) {
name: '<linked-deployment-name>'
params: {
<parameter-names-and-values>
}
}
Para implantar mais de uma instância de um módulo, adicione a for
expressão. Você pode usar o batchSize
decorador para especificar se as instâncias são implantadas em série ou em paralelo. Para obter mais informações, consulte Loops iterativos no 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>
}
}]
Assim como os recursos, os módulos são implantados em paralelo, a menos que dependam de outros módulos ou recursos. Normalmente, você não precisa definir dependências, pois elas são determinadas implicitamente. Se você precisar definir uma dependência explícita, poderá adicioná-la dependsOn
à definição do módulo. Para saber mais sobre dependências, consulte Dependências 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>
]
}
Caminho para o módulo
O arquivo para o módulo pode ser um arquivo local ou um arquivo externo. O arquivo externo pode estar na especificação do modelo ou em um registro do módulo Bicep.
Arquivo local
Se o módulo for um arquivo local, forneça um caminho relativo para esse arquivo. Todos os caminhos no Bicep devem ser especificados usando o separador de diretório de barra (/) para garantir uma compilação consistente entre plataformas. O caractere de barra invertida (\) do Windows não é suportado. Os caminhos podem conter espaços.
Por exemplo, para implantar um arquivo que está acima de um nível no diretório do seu arquivo principal, use:
module stgModule '../storageAccount.bicep' = {
name: 'storageDeploy'
params: {
storagePrefix: 'examplestg1'
}
}
Ficheiro no registo
Registo do módulo público
Nota
Os módulos não-AVM (Módulos Verificados do Azure) são retirados do registro do módulo público.
Os Módulos Verificados do Azure são módulos pré-criados, pré-testados e pré-verificados para implantar recursos no Azure. Criados e de propriedade de funcionários da Microsoft, esses módulos são projetados para simplificar e acelerar o processo de implantação de recursos e configurações comuns do Azure, ao mesmo tempo em que se alinham às práticas recomendadas; como o Well-Architected Framework.
Navegue até o ÍndiceBicep de Módulos Verificados do Azure para ver a lista de módulos disponíveis, selecione os números realçados na captura de tela a seguir para ser levado diretamente para essa exibição filtrada.
A lista de módulos mostra a versão mais recente. Selecione o número da versão para ver uma lista de versões disponíveis:
Para vincular a um módulo público, especifique o caminho do módulo com a seguinte sintaxe:
module <symbolic-name> 'br/public:<file-path>:<tag>' = {}
- br/public é o alias para módulos públicos. Você pode personalizar esse alias no arquivo de configuração do Bicep.
- O caminho do
/
arquivo pode conter segmentos que podem ser separados pelo caractere. - tag é usada para especificar uma versão para o módulo.
Por exemplo:
module storage 'br/public:avm/res/storage/storage-account:0.9.0' = {
name: 'myStorage'
params: {
name: 'store${resourceGroup().name}'
}
}
Nota
br/public é o alias para módulos públicos. Também pode ser escrito como:
module <symbolic-name> 'br:mcr.microsoft.com/bicep/<file-path>:<tag>' = {}
Registo do módulo privado
Se você publicou um módulo em um registro, pode vincular a esse módulo. Forneça o nome para o registro de contêiner do Azure e um caminho para o módulo. Especifique o caminho do módulo com a seguinte sintaxe:
module <symbolic-name> 'br:<registry-name>.azurecr.io/<file-path>:<tag>' = {
- br é o nome do esquema para um registro Bicep.
- o caminho do arquivo é chamado
repository
no Registro de Contêiner do Azure. O caminho do/
arquivo pode conter segmentos separados pelo caractere. - tag é usada para especificar uma versão para o módulo.
Por exemplo:
module stgModule 'br:exampleregistry.azurecr.io/bicep/modules/storage:v1' = {
name: 'storageDeploy'
params: {
storagePrefix: 'examplestg1'
}
}
Quando você faz referência a um módulo em um registro, a extensão Bicep no Visual Studio Code chama automaticamente bicep restore para copiar o módulo externo para o cache local. Leva alguns minutos para restaurar o módulo externo. Se o intellisense para o módulo não funcionar imediatamente, aguarde até que a restauração seja concluída.
O caminho completo para um módulo em um registro pode ser longo. Em vez de fornecer o caminho completo sempre que quiser usar o módulo, você pode configurar aliases no arquivo bicepconfig.json. Os aliases facilitam a referência ao módulo. Por exemplo, com um alias, você pode encurtar o caminho para:
module stgModule 'br/ContosoModules:storage:v1' = {
name: 'storageDeploy'
params: {
storagePrefix: 'examplestg1'
}
}
Um alias para o registro do módulo público foi predefinido:
module storage 'br/public:avm/res/storage/storage-account:0.9.0' = {
name: 'myStorage'
params: {
name: 'store${resourceGroup().name}'
}
}
Você pode substituir o alias público no arquivo bicepconfig.json.
Arquivo na especificação do modelo
Depois de criar uma especificação de modelo, você pode vincular a essa especificação de modelo em um módulo. Especifique a especificação do modelo no seguinte formato:
module <symbolic-name> 'ts:<sub-id>/<rg-name>/<template-spec-name>:<version>' = {
No entanto, você pode simplificar seu arquivo Bicep criando um alias para o grupo de recursos que contém suas especificações de modelo. Quando você usa um alias, a sintaxe se torna:
module <symbolic-name> 'ts/<alias>:<template-spec-name>:<version>' = {
O módulo a seguir implanta uma especificação de modelo para criar uma conta de armazenamento. A assinatura e o grupo de recursos para a especificação de modelo são definidos no alias chamado ContosoSpecs.
module stgModule 'ts/ContosoSpecs:storageSpec:2.0' = {
name: 'storageDeploy'
params: {
storagePrefix: 'examplestg1'
}
}
Use decoradores
Os decoradores são escritos no formato @expression
e são colocados acima das declarações do módulo. A tabela a seguir mostra os decoradores disponíveis para módulos.
Decorador | Argumento | Description |
---|---|---|
tamanho do lote | nenhum | Configure instâncias para implantar sequencialmente. |
descrição | string | Forneça descrições para o módulo. |
Os decoradores estão no namespace sys. Se você precisa diferenciar um decorador de outro item com o mesmo nome, prefacie o decorador com sys
. Por exemplo, se o arquivo Bicep incluir um parâmetro chamado description
, você deve adicionar o namespace sys ao usar o decorador de descrição .
Tamanho do lote
Você só pode aplicar @batchSize()
a uma definição de recurso ou módulo que usa uma for
expressão.
Por padrão, os módulos são implantados em paralelo. Ao adicionar o @batchSize(int)
decorador, você implanta instâncias em série.
@batchSize(3)
module storage 'br/public:avm/res/storage/storage-account:0.11.1' = [for storageName in storageAccounts: {
name: 'myStorage'
params: {
name: 'store${resourceGroup().name}'
}
}]
Para obter mais informações, consulte Implantar em lotes.
Description
Para adicionar explicação, adicione uma descrição às declarações do módulo. Por exemplo:
@description('Create storage accounts referencing an AVM.')
module storage 'br/public:avm/res/storage/storage-account:0.9.0' = {
name: 'myStorage'
params: {
name: 'store${resourceGroup().name}'
}
}
O texto formatado com marcação pode ser usado para o texto de descrição.
Parâmetros
Os parâmetros fornecidos na definição do módulo correspondem aos parâmetros no arquivo Bicep.
O exemplo de Bicep a seguir tem três parâmetros - storagePrefix, storageSKU e location. O parâmetro storageSKU tem um valor padrão para que você não precise fornecer um valor para esse parâmetro durante a implantação.
@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@2023-04-01' = {
name: uniqueStorageName
location: location
sku: {
name: storageSKU
}
kind: 'StorageV2'
properties: {
supportsHttpsTrafficOnly: true
}
}
output storageEndpoint object = stg.properties.primaryEndpoints
Para usar o exemplo anterior como um módulo, forneça valores para esses parâmetros.
targetScope = 'subscription'
@minLength(3)
@maxLength(11)
param namePrefix string
resource demoRG 'Microsoft.Resources/resourceGroups@2024-03-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
Definir o escopo do módulo
Ao declarar um módulo, você pode definir um escopo para o módulo que é diferente do escopo para o arquivo Bicep que contém. Use a scope
propriedade para definir o escopo do módulo. Quando a propriedade scope não é fornecida, o módulo é implantado no escopo de destino do pai.
O seguinte arquivo Bicep cria um grupo de recursos e uma conta de armazenamento nesse grupo de recursos. O arquivo é implantado em uma assinatura, mas o módulo tem o escopo definido para o novo grupo de recursos.
// 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@2024-03-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
O próximo exemplo implanta contas de armazenamento em dois grupos de recursos diferentes. Ambos os grupos de recursos já devem existir.
targetScope = 'subscription'
resource firstRG 'Microsoft.Resources/resourceGroups@2024-03-01' existing = {
name: 'demogroup1'
}
resource secondRG 'Microsoft.Resources/resourceGroups@2024-03-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'
}
}
Defina a propriedade scope como um objeto de escopo válido. Se o arquivo Bicep implantar um grupo de recursos, assinatura ou grupo de gerenciamento, você poderá definir o escopo de um módulo como o nome simbólico desse recurso. Ou, você pode usar as funções de escopo para obter um escopo válido.
Essas funções são:
O exemplo a seguir usa a managementGroup
função para definir o escopo.
param managementGroupName string
module mgDeploy 'main.bicep' = {
name: 'deployToMG'
scope: managementGroup(managementGroupName)
}
Saída
Você pode obter valores de um módulo e usá-los no arquivo Bicep principal. Para obter um valor de saída de um módulo, use a outputs
propriedade no objeto module.
O primeiro exemplo cria uma conta de armazenamento e retorna os pontos de extremidade primários.
@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@2023-04-01' = {
name: uniqueStorageName
location: location
sku: {
name: storageSKU
}
kind: 'StorageV2'
properties: {
supportsHttpsTrafficOnly: true
}
}
output storageEndpoint object = stg.properties.primaryEndpoints
Quando usado como módulo, você pode obter esse valor de saída.
targetScope = 'subscription'
@minLength(3)
@maxLength(11)
param namePrefix string
resource demoRG 'Microsoft.Resources/resourceGroups@2024-03-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
Próximos passos
- Para obter um tutorial, consulte Implantar recursos do Azure usando modelos do Bicep.
- Para passar um valor sensível para um módulo, use a função getSecret .