你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

Bicep modules

使用 Bicep,可以将部署组织成不同的模块。 模块是另一个 Bicep 文件部署的 Bicep 文件。 模块也可以是用于 JSON 的 Azure 资源管理器模板(ARM 模板)。 使用模块,可以通过对部署的复杂细节进行封装来提高 Bicep 文件的可读性。 你还可以轻松地将模块重用于不同的部署。

若要与组织中的其他人共享模块,请创建 模板规格专用注册表。 注册表中的模板规格和模块仅适用于具有正确权限的用户。

Tip

在模块注册表和模板规格之间进行的选择主要取决于偏好。 在两者之间进行选择时,需要考虑一些事项:

  • 模块注册表仅受 Bicep 支持。 如果未使用 Bicep,请使用模板规格。
  • 只能在 Bicep 模块注册表中从另一个 Bicep 文件部署内容。 可以直接从 API、Azure PowerShell、Azure CLI 和 Azure 门户部署模板规格。 您甚至可以使用 UiFormDefinition 来定制门户部署的体验。
  • Bicep 具有一些有限的功能,可以通过使用 loadTextContentloadFileAsBase64 函数来嵌入其他项目工件(包括非 Bicep 和非 ARM 模板文件,如 PowerShell 脚本、CLI 脚本以及其他二进制文件)。 模板规格无法打包这些工件。

Bicep 模块将转换为包含嵌套模板的单个 ARM 模板。 有关 Bicep 如何解析配置文件以及如何 Bicep 将用户定义的配置文件与默认配置文件合并的详细信息,请参阅 配置文件解析过程配置文件合并过程

Training resources

若要通过分步指南了解模块,请参阅 使用模块创建可组合的 Bicep 文件

Define modules

用于定义模块的基本语法是:

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

下面是一个简单的真实示例:

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

还可以将用于 JSON 的 ARM 模板用作模块:

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

使用符号名称引用 Bicep 文件另一部分中的模块。 例如,可以使用符号名称来获取模块的输出。 符号名称可以包含 a-z、A-Z、0-9 和下划线 (_)。 名称不能以数字开头。 模块不能与参数、变量或资源同名。

路径可以是本地文件,也可以是注册表中的文件。 本地文件可以是 Bicep 文件,也可以是 JSON 的 ARM 模板。 有关详细信息,请参阅模块的路径

name 属性为可选。 它将成为生成的模板中嵌套部署资源的名称。 如果未提供任何名称,则将生成一个 GUID 作为嵌套部署资源的名称。

如果将具有静态名称的模块同时部署到同一范围,那么其中一个部署可能会干扰来自另一个部署的输出。 例如,如果两个 Bicep 文件使用具有相同静态名称的同一模块(examplemodule)并且面向同一资源组,则一个部署可能会显示错误的输出。 如果担心在同一作用域内进行并发部署,请为模块提供一个独特的名称。 确保唯一模块名称的另一种方法是省略 name 属性,系统会自动生成唯一的模块名称。

以下示例将部署名称连接到模块名称。 如果为部署提供唯一名称,那么模块名称也是唯一的。

module stgModule 'storageAccount.bicep' = {
  name: '${deployment().name}-storageDeploy'
  scope: resourceGroup('demoRG')
}

不提供任何模块名称也是可以的。 将生成一个 GUID 作为模块名称。

module stgModule 'storageAccount.bicep' = {
  scope: resourceGroup('demoRG')
}

如果需要 指定不同于 主文件的作用域的范围,请添加 scope 属性。 有关详细信息,请参阅设置模块范围

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

若要有条件地部署模块,请添加 表达式if。 这类似于 有条件地部署资源

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

若要部署一个模块的多个实例,请添加 表达式。 batchSize使用修饰器指定是串行部署实例还是并行部署实例。 有关详细信息,请参阅 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>
  }
}]

与资源一样,模块会并行部署,除非它们依赖于其他模块或资源。 通常,无需设置依赖项,因为它们是隐式确定的。 如果需要设置显式依赖项,可在模块定义中添加 dependsOn。 若要了解有关依赖项的详细信息,请参阅 Bicep 中的资源依赖项

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

模块的路径

模块的文件可以是本地文件,也可以是外部文件。 外部文件可以在模板规格或 Bicep 模块注册表中。

Local file

如果模块是本地文件,请提供该文件的相对路径。 Bicep 中的所有路径都必须由正斜杠 (/) 目录分隔符指定,以确保跨平台进行一致的编译。 不支持 Windows 反斜杠 (\) 字符。 路径可以包含空格。

例如,若要从主文件中部署目录中一级以上的文件,请使用:

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

注册表中的文件

有公共和专用模块注册表。

公共模块注册表

Note

非 Azure 验证模块将从公共模块注册表中停用。

Azure 验证模块 是预生成、预测试的和可用于在 Azure 上部署资源的已验证模块。 Microsoft员工创建并拥有这些模块。 它们旨在简化和加速常见 Azure 资源和配置的部署过程。 这些模块还符合 Azure Well-Architected Framework 等最佳做法。

浏览 Bicep 模块 以查看可用的模块列表。 在以下屏幕截图中选择突出显示的数字,直接转到该筛选视图:

显示 Azure 验证模块的屏幕截图。

模块列表显示最新版本。 选择版本号以查看可用版本的列表。

显示 Azure 验证模块版本的屏幕截图。

若要链接到公共模块,请使用以下语法指定模块路径:

module <symbolic-name> 'br/public:<file-path>:<tag>' = {}
  • br/public:这是公共模块的别名。 可以在 Bicep 配置文件中自定义此别名。
  • 文件路径:可以包含可以使用字符分隔的 / 段。
  • 标记:用于指定模块的版本。

For example:

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

Note

公共模块的别名为 br/public. 还可以将其编写为:

module <symbolic-name> 'br:mcr.microsoft.com/bicep/<file-path>:<tag>' = {}

专用模块注册表

如果将 模块发布到注册表,则可以链接到该模块。 提供 Azure 容器注册表的名称和模块的路径。 使用以下语法指定模块路径:

module <symbolic-name> 'br:<registry-name>.azurecr.io/<file-path>:<tag>' = {
  • br: 是 Bicep 注册表的架构名称。
  • 文件路径:这在 Azure 容器注册表中称为repository。 文件路径可以包含由字符分隔的 / 段。
  • 标记:用于指定模块的版本。

For example:

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

在注册表中引用模块时,Visual Studio Code 中的 Bicep 扩展会自动调用 bicep restore 将外部模块复制到本地缓存。 还原外部模块需要片刻时间。 如果模块的 IntelliSense 无法立即工作,请等待还原完成。

注册表中模块的完整路径可能很长。 无需在每次使用模块时提供完整路径,而是 在 bicepconfig.json 文件中配置别名。 使用别名可以更方便地引用模块。 例如,使用别名可将路径缩短为:

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

公共模块注册表具有预定义的别名:

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

可以在 bicepconfig.json 文件中替代公共别名。

模板规格中的文件

创建 模板规格后,链接到模块中的该模板规格。 按以下格式指定模板规格:

module <symbolic-name> 'ts:<sub-id>/<rg-name>/<template-spec-name>:<version>' = {

若要简化 Bicep 文件,请为包含模板规格的资源组 创建别名 。 使用别名时,语法变为:

module <symbolic-name> 'ts/<alias>:<template-spec-name>:<version>' = {

以下模块部署了用于创建存储帐户的模板规格。 模板规格的订阅和资源组定义在别名 ContosoSpecs 中。

module stgModule 'ts/ContosoSpecs:storageSpec:2.0' = {
  name: 'storageDeploy'
  params: {
    storagePrefix: 'examplestg1'
  }
}

Use decorators

修饰器是以格式 @expression 编写的,放置在模块声明上方。 下表显示了模块的可用修饰器:

Decorator Argument Description
batchSize none 设置实例以按顺序部署。
description 字符串 提供模块的说明。

修饰器位于 sys 命名空间中。 如果需要将修饰器与具有相同名称的其他项区分开来,请在修饰器前面加上 sys。 例如,如果 Bicep 文件包含名为 description 的参数,则必须在使用 sys 修饰器时添加 description 命名空间。

BatchSize

只能将 @batchSize() 应用于使用 for 表达式的资源或模块定义。

默认情况下,模块会并行部署。 添加 @batchSize(int) 修饰器时,将串行部署实例。

@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}'
  }
}]

有关详细信息,请参阅批量部署

Description

若要添加解释,请将说明添加到模块声明。 For example:

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

可以使用 Markdown 格式的文本作为说明文本。

Parameters

模块定义中提供的参数与 Bicep 文件中的参数匹配。

以下 Bicep 示例具有三个参数:storagePrefixstorageSKUlocation。 该 storageSKU 参数具有默认值,因此在部署期间不必为该参数提供值。

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

output storageEndpoint object = stg.properties.primaryEndpoints

若要将前面的示例用作模块,请提供这些参数的值。

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

设置模块范围

声明模块时,应为模块设置与包含该模块的 Bicep 文件不同的作用域。 使用 scope 属性设置模块的范围。 如果未提供scope属性,则模块将部署到父目标作用域。

以下 Bicep 文件将创建一个资源组,并在该资源组中创建一个存储帐户。 该文件将部署到订阅,但模块的作用域限定为新资源组。

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

以下示例将存储帐户部署到两个不同的资源组。 这两个资源组都必须已存在。

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

scope 属性设置为有效的范围对象。 如果 Bicep 文件部署资源组、订阅或管理组,可以将模块的作用域设置为该资源的符号名称。 或者,可使用 scope 函数获取有效的范围。

这些函数包括:

下面的示例使用 managementGroup 函数来设置范围。

param managementGroupName string

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

Output

可以从模块获取值,并在主 Bicep 文件中使用这些值。 若要从模块获取输出值,请在模块对象上使用 outputs 属性。

第一个示例创建存储帐户并返回主要终结点:

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

output storageEndpoint object = stg.properties.primaryEndpoints

当属性用作模块时,可以获取该输出值:

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

使用 Bicep 版本 0.35.1 及更高版本, @secure() 修饰器可以应用于模块输出,将其标记为敏感,确保其值不会在日志或部署历史记录中公开。 当模块需要向父 Bicep 文件返回敏感数据(例如生成的密钥或连接字符串),而不会有风险暴露时,这非常有用。 有关详细信息,请参阅 安全输出