Partilhar via


Módulos bíceps

Com o Bicep, você pode organizar implantações em módulos. Um módulo é um ficheiro Bicep que outro ficheiro Bicep implementa. Um módulo também pode ser um modelo do Azure Resource Manager (modelo ARM) para JSON. Com os módulos, melhoras a legibilidade dos teus arquivos Bicep encapsulando detalhes complexos da tua implementaçã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 estão disponíveis apenas para usuários com as permissões corretas.

Tip

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 registo de módulos é suportado apenas pelo Bicep. Se não estiveres a usar o Bicep, utiliza as especificações de modelo.
  • Você pode implantar conteúdo no registo do módulo Bicep apenas a partir de um outro arquivo Bicep. Você pode implantar especificações de modelo 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 de projeto (incluindo arquivos de modelo não-Bicep e não-ARM, como scripts do PowerShell, scripts CLI e outros binários) usando as loadTextContent funções e loadFileAsBase64 . As especificações do modelo não podem empacotar esses artefatos.

Os módulos Bicep são convertidos em um único modelo ARM com modelos aninhados. Para obter mais informações sobre como o Bicep resolve arquivos de configuração e como o Bicep mescla um arquivo de configuração definido pelo usuário com o arquivo de configuração padrão, consulte Processo de resolução de arquivo de configuração e Processo de mesclagem de arquivo de configuração.

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

Um exemplo simples e real se parece com:

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

Você também pode usar um modelo ARM para JSON 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 ARM para JSON. Para obter mais informações, consulte Caminho para um módulo.

A name propriedade é opcional. Ele se torna o nome do recurso de implantação aninhado no modelo gerado. Se nenhum nome for indicado, um GUID será gerado como o nome do recurso de implementação aninhado.

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 usam o mesmo módulo com o mesmo nome estático (examplemodule) e são direcionados para o mesmo grupo de recursos, uma implantação pode 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. Outra maneira de garantir nomes de módulo exclusivos é deixar de fora a name propriedade, um nome de módulo exclusivo será gerado automaticamente.

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

Não fornecer nenhum nome de módulo também é válido. Um GUID será gerado como o nome do módulo.

module stgModule 'storageAccount.bicep' = {
  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. Isso é 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. Use o batchSize decorador para especificar se as instâncias são implantadas sequencialmente ou em paralelo. Para 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 porque elas são determinadas implicitamente. Se você precisar definir uma dependência explícita, adicione dependsOn à definição do módulo. Para saber mais sobre dependências, consulte Dependências de recursos no Bicep.

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 um módulo

O arquivo para o módulo pode ser um arquivo local ou um arquivo externo. O ficheiro externo pode estar numa especificação de modelo ou num registo de 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 pelo separador de diretório de barra oblíqua (/) para garantir uma compilação consistente entre diferentes plataformas. O carácter barra invertida (\) do Windows não é suportado. 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

Existem registos de módulos públicos e privados.

Registo do módulo público

Note

Os Módulos Não Verificados pela Azure são retirados do registo do módulo público.

Os Módulos Verificados do Azure são módulos pré-criados, pré-testados e pré-verificados que você pode usar para implantar recursos no Azure. Os funcionários da Microsoft criaram e possuem esses módulos. Eles foram projetados para simplificar e acelerar o processo de implantação de recursos e configurações comuns do Azure. Os módulos também se alinham às práticas recomendadas, como o Azure Well-Architected Framework.

Navegue pelos módulos Bicep para ver a lista de módulos disponíveis. Selecione os números realçados na captura de tela a seguir para ir diretamente para essa exibição filtrada:

Captura de ecrã que mostra os Módulos Verificados do Azure.

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.

Captura de ecrã que mostra as versões dos Módulos Verificados do Azure.

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: Este é o alias para módulos públicos. Você pode personalizar esse alias no arquivo de configuração do Bicep.
  • caminho do arquivo: pode conter segmentos que você pode separar com o / caractere.
  • tag: é usada para especificar uma versão para o módulo.

Por exemplo:

module storage 'br/public:avm/res/storage/storage-account:0.18.0' = {
  name: 'myStorage'
  params: {
    name: 'store${resourceGroup().name}'
  }
}

Note

O alias para módulos públicos é br/public. Você também pode escrevê-lo 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, você 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: Este é um nome de esquema para um registo Bicep.
  • caminho do arquivo: isso é chamado repository no Registro de Contêiner do Azure. O caminho do ficheiro pode conter segmentos que estão separados pelo caractere /.
  • tag: É usado 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 bicep restore automaticamente 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 a conclusão da restauração.

O caminho completo para um módulo em um registro pode ser longo. Em vez de fornecer o caminho completo sempre que você quiser usar o módulo, configure 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'
  }
}

O registro do módulo público tem um alias predefinido:

module storage 'br/public:avm/res/storage/storage-account:0.18.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, vincule-se 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>' = {

Para simplificar o arquivo Bicep, crie um alias para o grupo de recursos que contém as especificações do 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

Decoradores são escritos no formato @expression e são colocados acima das declarações de módulo. A tabela a seguir mostra os decoradores disponíveis para módulos:

Decorator Argument Description
batchSize none Configure instâncias para implantar sequencialmente.
description cadeia (de caracteres) Forneça descrições para o módulo.

Os decoradores estão no namespace do 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ê deverá adicionar o sys namespace ao usar o description decorador.

BatchSize

Você pode aplicar @batchSize() somente 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.18.0' = {
  name: 'myStorage'
  params: {
    name: 'store${resourceGroup().name}'
  }
}

Você pode usar texto formatado em Markdown para o texto de descrição.

Parameters

Os parâmetros fornecidos na definição do módulo correspondem aos parâmetros no arquivo Bicep.

O exemplo de Bíceps a seguir tem três parâmetros: storagePrefix, storageSKUe location. O storageSKU parâmetro tem um valor padrão, portanto, você não precisa 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@2025-06-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@2025-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

Definir o escopo do módulo

Ao declarar um módulo, defina um escopo para o módulo que seja diferente do escopo do arquivo Bicep que o contém. Use a scope propriedade para definir o escopo do módulo. Quando a scope propriedade não é fornecida, o módulo é implantado no escopo de destino do elemento pai.

O seguinte arquivo Bicep cria um grupo de recursos e uma conta de armazenamento nesse grupo de recursos. O arquivo é implantado numa subscrição, 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@2025-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

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@2025-04-01' existing = {
  name: 'demogroup1'
}

resource secondRG 'Microsoft.Resources/resourceGroups@2025-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'
  }
}

Defina a scope propriedade como um objeto de escopo válido. Se o seu ficheiro Bicep implementar um grupo de recursos, uma subscrição ou um grupo de gestão, pode definir o âmbito de um módulo para 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)
}

Output

Você pode obter valores de um módulo e usá-los no arquivo principal do Bicep. Para obter um valor de saída de um módulo, use a outputs propriedade no objeto módulo.

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@2025-06-01' = {
  name: uniqueStorageName
  location: location
  sku: {
    name: storageSKU
  }
  kind: 'StorageV2'
  properties: {
    supportsHttpsTrafficOnly: true
  }
}

output storageEndpoint object = stg.properties.primaryEndpoints

Quando a propriedade é usada como um módulo, você pode obter esse valor de saída:

targetScope = 'subscription'

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

resource demoRG 'Microsoft.Resources/resourceGroups@2025-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

Com a versão 0.35.1 do Bicep e posteriores, o decorador @secure() pode ser aplicado às saídas do módulo para marcá-las como sensíveis, garantindo que os seus valores não sejam expostos em registos ou no histórico de implantação. Isso é útil quando um módulo precisa retornar dados confidenciais, como uma chave gerada ou cadeia de conexão, para o arquivo Bicep pai sem correr o risco de exposição. Para obter mais informações, consulte Saídas seguras.

Identidade do módulo

A partir da versão 0.36.1 do Bicep, você pode atribuir uma identidade gerenciada atribuída pelo usuário a um módulo. Isto torna a identidade disponível dentro do módulo — por exemplo, para aceder a um Cofre de Chaves. No entanto, esse recurso destina-se ao uso futuro e ainda não é suportado pelos serviços de back-end.

param identityId string

module mod './module.bicep' = {
  identity: {
    type: 'UserAssigned'
    userAssignedIdentities: {
      '${identityId}': {}
    }
  }
  name: 'mod'
  params: {
    keyVaultUri: 'keyVaultUri'
    identityId: identityId
  }
}
  • Para passar um valor sensível para um módulo, use a getSecret função.