Bicep 中的 Azure 资源管理器模板规格

模板规格是一种资源类型,用于存储 Azure 资源管理器模板(ARM 模板),以便之后进行部署。 通过该资源类型,你可以与组织中的其他用户共享 ARM 模板。 与任何其他 Azure 资源一样,你可以使用 Azure 基于角色的访问控制 (Azure RBAC) 来共享模板规格。你可以使用 Azure CLI 或 Azure PowerShell 通过提供 Bicep 文件来创建模板规格。 Bicep 文件将在存储之前被转换为 ARM JSON 模板。 目前,无法通过从 Azure 门户导入 Bicep 文件来创建模板规格资源。

Microsoft.Resources/templateSpecs 是模板规格的资源类型。 它包含一个主模板和任意数量的链接模板。 Azure 将模板规格安全存储在资源组中。 主模板和链接模板都必须是 JSON。 模板规格支持版本控制

若要部署模板规格,请使用标准 Azure 工具(如 PowerShell)、Azure CLI、Azure 门户、REST 和其他受支持的 SDK 和客户端。 请使用与模板或 Bicep 文件相同的命令。

注意

要将 Bicep 中的模板规格与 Azure PowerShell 结合使用,必须安装 6.3.0 或更高版本。 要将其与 Azure CLI 一起使用,请使用 2.27.0 或更高版本

设计部署时,应始终考虑资源的生命周期,并将具有相似生命周期的资源分组到单个模板规范。例如,你的部署包括多个 Azure Cosmos DB 实例,其中每个实例都包含自己的数据库和容器。 鉴于数据库和容器没有太大变化,你需要创建一个模板规范,使其包括 Cosmo DB 实例及其基础数据库和容器。 然后,你可以在 Bicep 中使用条件语句以及复制循环来创建这些资源的多个实例。

提示

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

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

培训资源

要了解有关模板规格的详细信息以及实践指导,请参阅使用模板规格发布可重用基础结构代码库

所需的权限

为模板规范定义了两个 Azure 内置角色:

此外,还需要部署 Bicep 文件的权限。 请参阅部署 - CLI部署 - PowerShell

为什么使用模板规格?

模板规格具有以下优势:

  • 可以使用标准 ARM 模板或 Bicep 文件作为模板规格。
  • 可以通过 Azure RBAC 而不是 SAS 令牌来管理访问。
  • 用户无需对 Bicep 文件具有写入权限即可部署模板规格。
  • 可以将模板规格集成到现有的部署过程中,例如 PowerShell 脚本或 DevOps 管道。

使用模板规格,可以创建规范化的模板并与组织中的团队共享。 模板规格是安全的,因为 Azure 资源管理器可使用它进行部署,而没有正确权限的用户则无法访问。 用户只需具有模板规格的读取访问权限即可部署模板,因此可以在不允许其他人进行修改的情况下共享该模板。

如果 GitHub 存储库或存储帐户中当前有模板,在尝试共享和使用这些模板时会遇到一些困难。 若要部署模板,需要使模板要么可公开访问,要么使用 SAS 令牌管理访问。 为了避免此限制,用户可能会创建本地副本,这些副本最终会偏离原始模板。 模板规格简化了共享模板。

模板规格中包含的模板应由组织中的管理员按照组织的要求和指南进行验证。

创建模板规格

以下示例显示了用于在 Azure 中创建存储帐户的简单 Bicep 文件。

@allowed([
  'Standard_LRS'
  'Standard_GRS'
  'Premium_LRS'
])
param storageAccountType string = 'Standard_LRS'

resource stg 'Microsoft.Storage/storageAccounts@2023-04-01' = {
  name:  'store${uniqueString(resourceGroup().id)}'
  location: resourceGroup().location
  sku: {
    name: storageAccountType
  }
  kind:'StorageV2'
}

使用以下命令创建模板规格:

New-AzTemplateSpec -Name storageSpec -Version 1.0a -ResourceGroupName templateSpecsRg -Location chinanorth2 -TemplateFile ./mainTemplate.bicep

你还可以使用 Bicep 文件创建模板规格。 但是,mainTemplate 的内容必须是 JSON。 以下模板创建用于部署存储帐户的模板规范:

param templateSpecName string = 'CreateStorageAccount'
param templateSpecVersionName string = '0.1'
param location string = resourceGroup().location

resource createTemplateSpec 'Microsoft.Resources/templateSpecs@2022-02-01' = {
  name: templateSpecName
  location: location
  properties: {
    description: 'A basic templateSpec - creates a storage account.'
    displayName: 'Storage account (Standard_LRS)'
  }
}

resource createTemplateSpecVersion 'Microsoft.Resources/templateSpecs/versions@2022-02-01' = {
  parent: createTemplateSpec
  name: templateSpecVersionName
  location: location
  properties: {
    mainTemplate: {
      '$schema': 'https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#'
      'contentVersion': '1.0.0.0'
      'parameters': {
        'storageAccountType': {
          'type': 'string'
          'defaultValue': 'Standard_LRS'
          'allowedValues': [
            'Standard_LRS'
            'Standard_GRS'
            'Standard_ZRS'
            'Premium_LRS'
          ]
        }
      }
      'resources': [
        {
          'type': 'Microsoft.Storage/storageAccounts'
          'apiVersion': '2023-04-01'
          'name': 'store$uniquestring(resourceGroup().id)'
          'location': resourceGroup().location
          'kind': 'StorageV2'
          'sku': {
            'name': '[parameters(\'storageAccountType\')]'
          }
        }
      ]
    }
  }
}

Bicep 文件中嵌入的 JSON 模板需要进行以下更改:

  • 删除行尾的逗号。
  • 将双引号替换为单引号。
  • 对表达式中的单引号进行转义。 例如 'name': '[parameters(\'storageAccountType\')]'
  • 要访问 Bicep 文件中定义的参数和变量,可以直接使用参数名称和变量名称。 要访问 mainTemplate 中定义的参数和变量,仍然需要使用 ARM JSON 模板语法。 例如 'name': '[parameters(\'storageAccountType\')]'
  • 使用 Bicep 语法调用 Bicep 函数。 例如,'location': resourceGroup().location。

模板规格的大小限制为大约 2 MB。 如果模板规格大小超过限制,则会出现 TemplateSpecTooLarge 错误代码。 错误消息显示:

The size of the template spec content exceeds the maximum limit. For large template specs with many artifacts, the recommended course of action is to split it into multiple template specs and reference them modularly via TemplateLinks.

可以使用以下命令查看订阅中的所有模板规格:

Get-AzTemplateSpec

可以使用以下命令查看模板规格的详细信息(包括其版本):

Get-AzTemplateSpec -ResourceGroupName templateSpecsRG -Name storageSpec

部署模板规格

创建模板规范后,具有模板规格读取者角色的用户可以部署它。 此外,还需要部署 ARM 模板的权限。 请参阅部署 - CLI部署 - PowerShell

可通过门户、PowerShell、Azure CLI 部署模板规格,或者在更大型的模板部署中将其作为 Bicep 模块进行部署。 组织中的用户可以将模板规格部署到 Azure 中的任何范围(资源组、订阅、管理组或租户)。

可通过提供模板规格的资源 ID 来部署该模板规格,而无需传递 Bicep 文件的路径或 URI。 资源 ID 采用以下格式:

/subscriptions/{subscription-id}/resourceGroups/{resource-group}/providers/Microsoft.Resources/templateSpecs/{template-spec-name}/versions/{template-spec-version}

请注意,资源 ID 包括模板规格的版本名称。

例如,可以使用以下命令部署模板规格。

$id = "/subscriptions/11111111-1111-1111-1111-111111111111/resourceGroups/templateSpecsRG/providers/Microsoft.Resources/templateSpecs/storageSpec/versions/1.0a"

New-AzResourceGroupDeployment `
  -TemplateSpecId $id `
  -ResourceGroupName demoRG

实际上,通常需要运行 Get-AzTemplateSpecaz ts show 来获取要部署的模板规格的 ID。

$id = (Get-AzTemplateSpec -Name storageSpec -ResourceGroupName templateSpecsRg -Version 1.0a).Versions.Id

New-AzResourceGroupDeployment `
  -ResourceGroupName demoRG `
  -TemplateSpecId $id

还可以打开以下格式的 URL 以部署模板规格:

https://portal.azure.cn/#create/Microsoft.Template/templateSpecVersionId/%2fsubscriptions%2f{subscription-id}%2fresourceGroups%2f{resource-group-name}%2fproviders%2fMicrosoft.Resources%2ftemplateSpecs%2f{template-spec-name}%2fversions%2f{template-spec-version}

参数

将参数传递到模板规格与将参数传递到 Bicep 文件的过程类似。 以内联方式添加参数值或将参数值添加到参数文件中。

内联参数。

若要以内联方式传递参数,请使用:

New-AzResourceGroupDeployment `
  -TemplateSpecId $id `
  -ResourceGroupName demoRG `
  -StorageAccountType Standard_GRS

参数文件

  • 使用 Bicep 参数文件

    若要创建 Bicep 参数文件,必须指定 using 语句。 下面是一个示例:

    using 'using 'ts:<subscription-id>/<resource-group-name>/<template-spec-name>:<tag>'
    
    param StorageAccountType = 'Standard_GRS'
    

    有关详细信息,请参阅 Bicep 参数文件

    可使用以下方式传递参数文件:

    目前,无法使用 Azure PowerShell 部署包含 .bicepparam 文件的模板规范。

  • 使用 JSON 参数文件

    以下 JSON 是示例 JSON 参数文件:

    {
      "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
      "contentVersion": "1.0.0.0",
      "parameters": {
        "StorageAccountType": {
          "value": "Standard_GRS"
        }
      }
    }
    

    并使用以下命令传递该参数文件:

    New-AzResourceGroupDeployment `
      -TemplateSpecId $id `
      -ResourceGroupName demoRG `
      -TemplateParameterFile ./mainTemplate.parameters.json
    

版本控制

创建模板规格时,需要为其提供版本名称。 循环访问模板代码时,可以更新现有版本(获取补丁)或发布新版本。 版本是文本字符串。 可以选择遵循任意版本控制系统,包括语义化版本控制。 模板规格的用户可提供部署模板规格时要使用的版本名称。 可以拥有无限数量的版本。

使用标记

可以通过标记对资源进行逻辑组织。 可以使用 Azure PowerShell 和 Azure CLI 将标记添加到模板规格。 以下示例演示如何在创建模板规格时指定标记:

New-AzTemplateSpec `
  -Name storageSpec `
  -Version 1.0a `
  -ResourceGroupName templateSpecsRg `
  -Location chinanorth2 `
  -TemplateFile ./mainTemplate.bicep `
  -Tag @{Dept="Finance";Environment="Production"}

下一个示例演示如何在更新现有模板规格时应用标记:

Set-AzTemplateSpec `
  -Name storageSpec `
  -Version 1.0a `
  -ResourceGroupName templateSpecsRg `
  -Location chinanorth2 `
  -TemplateFile ./mainTemplate.bicep `
  -Tag @{Dept="Finance";Environment="Production"}

模板及其版本都可以有标记。 根据指定的参数应用或继承标记。

模板规格 版本 版本参数 标记参数 标记值
Exists 空值 未指定 Specified 已应用于模板规格
Exists 新建 Specified 未指定 已从模板规格继承到版本
新建 新建 Specified Specified 已同时应用于模板规格和版本
Exists 新建 Specified Specified 已应用于版本
Exists Exists Specified Specified 已应用于版本

创建模板规格后,可以在 Bicep 模块中链接到该模板规格。 部署包含该模块的 Bicep 文件时,将部署模板规格。 有关详细信息,请参阅模板规格中的文件

若要为用于模块链接的模板规范创建别名,请参阅模块的别名

后续步骤

要了解有关模板规格的详细信息以及实践指导,请参阅使用模板规格发布可重用基础结构代码库