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

在 Bicep 中创建并部署 Azure 部署堆栈

Azure 部署堆栈是一种资源,可让你将一组 Azure 资源作为单个凝聚单元进行管理。 将 Bicep 文件或 Azure 资源管理器 JSON 模板(ARM JSON 模板)提交到部署堆栈时,可以定义堆栈管理的资源。 如果从模板中删除资源,则可以根据部署堆栈的指定 actionOnUnmanage 行为将其分离或删除。 可以使用 Azure 基于角色的访问控制(Azure RBAC)限制对部署堆栈的访问,类似于其他 Azure 资源。

若要创建和更新部署堆栈,请使用 Azure CLI、Azure PowerShell 或 Azure 门户和 Bicep 文件。 堆栈将这些 Bicep 文件转入 ARM JSON 模板,并将其部署为部署对象。 部署堆栈提供除 熟悉的部署资源 之外的其他功能,并且是这些功能的超集。

Microsoft.Resources/deploymentStacks 是部署堆栈的资源类型。 它包含一个主模板,该模板可以跨范围对资源执行一对多更新,并阻止对这些资源所做的任何不需要的更改。

规划部署并确定哪些资源组应属于同一堆栈时,请考虑这些资源的管理生命周期,包括创建、更新和删除。 例如,可能需要为不同资源组范围内的各种应用程序团队预配一些测试虚拟机。 可以使用部署堆栈创建这些测试环境,并通过对部署堆栈的后续更新更新测试虚拟机配置。 完成项目后,您需要删除创建的任何资源,例如测试虚拟机。 使用部署堆栈并指定相应的删除标志来删除托管资源。 这种方法更简便,可以在清理环境期间节省时间,因为其只涉及对堆栈资源进行一次更新,而不用一个一个去修改或删除各个资源组范围内的每个测试用虚拟机。

部署堆栈需要 Azure PowerShell 12.0.0 或更高版本 或 Azure CLI 2.61.0 或更高版本

请跟随教程完成快速入门:创建部署堆栈,创建你的第一个部署堆栈。

为什么使用部署堆栈?

部署堆栈提供以下优势:

  • 将不同范围内的资源整合为一个统一实体,简化其预配和管理。
  • 通过拒绝设置防止对受管理资源进行不需要的修改。
  • 在部署堆栈更新期间使用删除标记来高效清理环境。
  • 为部署堆栈使用标准模板,例如 Bicep、ARM 模板或模板规格。

已知的限制

  • 在单个范围内创建部署堆栈的数量上限为800个。
  • 任意给定范围内最多可以存在 2,000 个拒绝分配。
  • 部署堆栈不管理隐式创建的资源。 因此,不能对这些资源使用拒绝分配或清理。
  • 拒绝分配不支持标记。
  • 管理组范围内不支持拒绝分配。 但是,如果部署指向订阅范围,则管理组堆栈支持拒绝分配。
  • 部署堆栈无法删除密钥保管库机密。 如果要从模板中删除密钥保管库机密,请确保也使用分离模式执行部署堆栈更新/删除命令。

已知问题

  • 删除资源组的操作目前会绕过拒绝分配。 在资源组范围内创建部署堆栈时,Bicep 文件不包含资源组的定义。 尽管拒绝分配设置,但可以删除资源组及其包含的堆栈。 但是,如果在组内的任何资源上处于活动状态,则删除操作将失败。
  • What-if 支持尚不可用。
  • 管理组范围的堆栈无法部署到另一个管理组。 它只能部署到堆栈本身的管理组,或部署到子订阅。
  • Azure PowerShell 命令可帮助列出 DeleteResourcesAndResourcesGroups 开关的 ActionOnUnmanage 值。 使用此值时,该命令会分离托管资源和资源组。 在下一次更新中删除此值。 不要使用此值。
  • 在某些情况下,New 和 Set Azure PowerShell cmdlet 可能会返回一个通用的模板验证错误,且无法明确如何解决该问题。 下一个版本中将修复此 bug。 如果错误不清楚,请在调试模式下运行 cmdlet,以查看原始响应中更详细的错误。
  • Microsoft Graph 提供程序 不支持部署堆栈。

内置角色

警告

RBAC 权限 Microsoft.Resources/deploymentStacks/manageDenySetting/action 的强制实施将在包括政府云在内的各个区域推广。

部署堆栈有两个内置角色:

  • Azure 部署堆栈参与者:用户可以管理部署堆栈,但无法在部署堆栈中创建或删除拒绝分配。
  • Azure 部署堆栈所有者:用户可以管理部署堆栈,包括那些具有拒绝分配的用户。

创建部署堆栈

可以在资源组、订阅或管理组范围内创建部署堆栈资源。 在目标范围内,您提供的部署堆栈模板定义了要创建或更新的资源。

  • 资源组范围内的堆栈可以将模板部署到部署堆栈所在的同一资源组。
  • 订阅范围内的堆栈可以将模板部署到资源组或部署堆栈所在的同一订阅。
  • 在管理组范围内的堆栈可以将模板部署到订阅服务。

请务必注意,在存在部署堆栈的位置,使用拒绝设置功能创建的拒绝分配也会存在。 例如,通过创建在订阅范围内、将模板部署到资源组范围的部署堆栈,且拒绝设置模式为 DenyDelete 时,可以轻松将受管理资源预配到指定的资源组,并阻止有人尝试删除这些资源。 此方法通过在订阅级别而不是资源组级别分隔部署堆栈的安全性,从而帮助你增强部署堆栈的安全性。 这种分离可确保使用预配资源的开发人员团队仅对资源组具有可见性和写入访问权限。 部署堆栈在更高级别保持隔离。 此配置可最大程度地减少可以编辑部署堆栈并对其拒绝分配进行更改的用户数。 有关详细信息,请参阅防止受管理资源被删除

还可以使用 create-stack 命令 更新部署堆栈

要在资源组范围内创建部署堆栈,请执行以下操作:

New-AzResourceGroupDeploymentStack `
  -Name "<deployment-stack-name>" `
  -ResourceGroupName "<resource-group-name>" `
  -TemplateFile "<bicep-file-name>" `
  -ActionOnUnmanage "detachAll" `
  -DenySettingsMode "none"

若要在订阅范围内创建部署堆栈,请执行以下操作:

New-AzSubscriptionDeploymentStack `
  -Name "<deployment-stack-name>" `
  -Location "<___location>" `
  -TemplateFile "<bicep-file-name>" `
  -DeploymentResourceGroupName "<resource-group-name>" `
  -ActionOnUnmanage "detachAll" `
  -DenySettingsMode "none"

参数 “DeploymentResourceGroupName” 指定用于存储受管理资源的资源组。 如果未指定参数,托管资源将存储在订阅范围内。

要在管理组范围内创建部署堆栈,请执行以下操作:

New-AzManagementGroupDeploymentStack `
  -Name "<deployment-stack-name>" `
  -Location "<___location>" `
  -TemplateFile "<bicep-file-name>" `
  -DeploymentSubscriptionId "<subscription-id>" `
  -ActionOnUnmanage "detachAll" `
  -DenySettingsMode "none"

参数 “deploymentSubscriptionId” 指定用于存储受管理资源的订阅。 如果未指定参数,则托管资源将存储在管理组范围内。

列出部署堆栈

若要列出资源组范围内的部署堆栈资源,请执行以下操作:

Get-AzResourceGroupDeploymentStack `
  -ResourceGroupName "<resource-group-name>"

要列出在订阅范围内的部署堆栈资源,请执行以下操作:

Get-AzSubscriptionDeploymentStack

要列出管理组范围内的部署堆栈资源,请执行以下操作:

Get-AzManagementGroupDeploymentStack `
  -ManagementGroupId "<management-group-id>"

更新部署堆栈

若要更新部署堆栈(可能涉及添加或删除受管理资源),需要对基础 Bicep 文件进行更改。 进行修改后,可以通过运行更新命令或重新运行 create 命令来更新部署堆栈。

基础结构即代码设计模式可让你完全控制托管资源列表。

使用 Set 命令

要在资源组范围内更新部署堆栈,请执行以下操作:

Set-AzResourceGroupDeploymentStack `
  -Name "<deployment-stack-name>" `
  -ResourceGroupName "<resource-group-name>" `
  -TemplateFile "<bicep-file-name>" `
  -ActionOnUnmanage "detachAll" `
  -DenySettingsMode "none"

要在订阅范围内更新部署堆栈,请执行以下操作:

Set-AzSubscriptionDeploymentStack `
  -Name "<deployment-stack-name>" `
  -Location "<___location>" `
  -TemplateFile "<bicep-file-name>" `
  -DeploymentResourceGroupName "<resource-group-name>" `
  -ActionOnUnmanage "detachAll" `
  -DenySettingsMode "none"

参数 “DeploymentResourceGroupName” 指定用于存储部署堆栈资源的资源组。 如果未指定资源组名称,则部署堆栈服务会为你创建新的资源组。

要在管理组范围内更新部署堆栈,请执行以下操作:

Set-AzManagementGroupDeploymentStack `
  -Name "<deployment-stack-name>" `
  -Location "<___location>" `
  -TemplateFile "<bicep-file-name>" `
  -DeploymentSubscriptionId "<subscription-id>" `
  -ActionOnUnmanage "detachAll" `
  -DenySettingsMode "none"

使用 New 命令

你会收到如下所示的警告:

The deployment stack 'myStack' you're trying to create already exists in the current subscription/management group/resource group. Do you want to overwrite it? Detaching: resources, resourceGroups (Y/N)

有关详细信息,请参阅创建部署堆栈

控制分离和删除

分离的资源(或非托管资源)是指部署堆栈未跟踪或管理但仍存在于 Azure 中的资源。

若要指示 Azure 删除非托管资源,请使用 create stack 命令更新堆栈并包括 ActionOnUnmanage 交换机。 有关详细信息,请参阅创建部署堆栈

使用 ActionOnUnmanage 开关定义在更新或删除堆栈后不再受管理的资源会发生什么情况。 允许值包括:

  • deleteAll:如果是受管理资源和资源组,请使用删除而不是分离。
  • deleteResources:如果只有受管理资源,请使用删除而不是拆离。
  • detachAll:拆离受管理资源和资源组。

例如:

New-AzSubscriptionDeploymentStack `
  -Name "<deployment-stack-name" `
  -TemplateFile "<bicep-file-name>" `
  -DenySettingsMode "none" `
  -ActionOnUnmanage "deleteAll" 

警告

删除action-on-unmanage开关设置为deleteAll的资源组时,将删除托管资源组及其包含的所有资源。

处理堆栈不同步错误

更新或删除部署堆栈时,可能会遇到以下堆栈不同步错误,指示堆栈资源列表未正确同步。

The deployment stack '{0}' might not have an accurate list of managed resources. To prevent resources from being accidentally deleted, check that the managed resource list doesn't have any additional values. If there is any uncertainty, it's recommended to redeploy the stack with the same template and parameters as the current iteration. To bypass this warning, specify the 'BypassStackOutOfSyncError' flag.

可以从 Azure 门户获取资源列表,或者使用相同的参数重新部署当前部署的 Bicep 文件。 输出显示受管理资源。

...
Resources: /subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/demoRg/providers/Microsoft.Network/virtualNetworks/vnetthmimleef5fwk
           /subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/demoRg/providers/Microsoft.Storage/storageAccounts/storethmimleef5fwk

在查看并验证堆栈中的资源列表后,请在 Azure PowerShell 中使用开关 BypassStackOutOfSyncError 或在 Azure CLI 中使用 bypass-stack-out-of-sync-error 重新运行命令。 仅在彻底查看堆栈中的资源列表后使用此开关。 默认情况下不要使用此开关。

删除部署堆栈

ActionOnUnmanage 开关定义针对不再受管理的资源的操作。 该开关具有以下值:

  • DeleteAll:删除资源和资源组。
  • DeleteResources:仅删除资源。
  • DetachAll:拆离资源。

即使指定了删除所有开关,部署堆栈所在的资源组中的非托管资源也会阻止非托管资源和资源组本身被删除。

要删除资源组范围内的部署堆栈资源,请执行以下操作:

Remove-AzResourceGroupDeploymentStack `
  -name "<deployment-stack-name>" `
  -ResourceGroupName "<resource-group-name>" `
  -ActionOnUnmanage "<deleteAll/deleteResources/detachAll>"

要删除在订阅范围内的部署堆栈资源,请执行以下操作:

Remove-AzSubscriptionDeploymentStack `
  -Name "<deployment-stack-name>" `
  -ActionOnUnmanage "<deleteAll/deleteResources/detachAll>"

要删除管理组范围内的部署堆栈资源,请执行以下操作:

Remove-AzManagementGroupDeploymentStack `
  -Name "<deployment-stack-name>" `
  -ManagementGroupId "<management-group-id>" `
  -ActionOnUnmanage "<deleteAll/deleteResources/detachAll>"

查看部署堆栈中的受管理资源

部署堆栈服务尚不提供 Azure 门户图形用户界面 (GUI)。 若要查看部署堆栈中的托管资源,请使用以下 Azure PowerShell/Azure CLI 命令:

要查看资源组范围内的受管理资源,请执行以下操作:

(Get-AzResourceGroupDeploymentStack -Name "<deployment-stack-name>" -ResourceGroupName "<resource-group-name>").Resources

要查看订阅范围内的受管理资源,请执行以下操作:

(Get-AzSubscriptionDeploymentStack -Name "<deployment-stack-name>").Resources

要查看管理组范围内的受管理资源,请执行以下操作:

(Get-AzManagementGroupDeploymentStack -Name "<deployment-stack-name>" -ManagementGroupId "<management-group-id>").Resources

将资源添加到部署堆栈

要添加受管理资源,请将资源定义添加到基础 Bicep 文件,然后运行更新命令或重新运行创建命令。 有关详细信息,请参阅更新部署堆栈

从部署堆栈中删除受管理资源

要删除受管理资源,请从基础 Bicep 文件中删除资源定义,然后运行更新命令或重新运行创建命令。 有关详细信息,请参阅更新部署堆栈

保护受管理资源

你可以分配对部署堆栈的托管资源的特定权限,以防止未经授权的安全主体删除或更新这些资源。 这些权限称为拒绝设置。 将堆栈存储在父范围。 例如,要保护订阅中的资源,请将堆栈置于父范围,即直接的父管理组。

拒绝设置仅应用于控制平面操作,不应用于数据平面操作。 例如,可以通过控制平面创建存储帐户和密钥保管库,这意味着部署堆栈管理它们。 但是,可以通过数据平面创建子资源(如机密或 Blob 容器),这意味着部署堆栈无法管理它们。

拒绝设置仅应用于显式创建的资源,不应用于隐式创建的资源。 例如,托管 AKS 群集会创建多个其他服务(例如虚拟机)来支持它。 在这种情况下,由于虚拟机未在 Bicep 文件中定义,并且是隐式创建的资源,因此它不受部署堆栈拒绝设置的约束。

注意

最新版本需要在堆栈范围内具有特定权限以便:

  • 创建或更新部署堆栈,并将拒绝设置配置为 None 之外的值。
  • 更新或删除现有拒绝设置值不为 None 的部署堆栈。

使用部署堆栈内置角色来授予权限。

Azure PowerShell 包含以下参数,用于自定义拒绝分配:

  • DenySettingsMode:定义禁止对受管理资源进行的操作,以防止未经授权的安全主体尝试删除或更新这些资源。 只要您不明确授予访问权限,则此限制适用于所有人。 值包括:NoneDenyDeleteDenyWriteAndDelete
  • DenySettingsApplyToChildScopes:指定后,拒绝设置模式配置也应用于受管理资源的子范围。 例如,某个 Bicep 文件定义了 Microsoft.Sql/servers 资源(父)和 Microsoft.Sql/servers/databases 资源(子)。 如果创建包含启用DenySettingsApplyToChildScopes设置且DenySettingsMode设置为DenyWriteAndDelete的 Bicep 文件的部署堆栈,则不能向 Microsoft.Sql/servers 资源或 Microsoft.Sql/servers/databases 资源添加任何额外的子资源。
  • DenySettingsExcludedAction:排除在拒绝设置之外的基于角色的管理操作的列表。 最多允许 200 次操作。
  • DenySettingsExcludedPrincipal:排除在锁定之外的 Microsoft Entra 主体 ID 的列表。 最多允许 5 个主体。

要在资源组范围内应用拒绝设置,请执行以下操作:

New-AzResourceGroupDeploymentStack `
  -Name "<deployment-stack-name>" `
  -ResourceGroupName "<resource-group-name>" `
  -TemplateFile "<bicep-file-name>" `
  -ActionOnUnmanage "detachAll" `
  -DenySettingsMode "denyDelete" `
  -DenySettingsExcludedAction "Microsoft.Compute/virtualMachines/write Microsoft.StorageAccounts/delete" `
  -DenySettingsExcludedPrincipal "<object-id>,<object-id>"

要在订阅范围内应用拒绝设置,请执行以下操作:

New-AzSubscriptionDeploymentStack `
  -Name "<deployment-stack-name>" `
  -Location "<___location>" `
  -TemplateFile "<bicep-file-name>" `
  -ActionOnUnmanage "detachAll" `
  -DenySettingsMode "denyDelete" `
  -DenySettingsExcludedAction "Microsoft.Compute/virtualMachines/write Microsoft.StorageAccounts/delete" `
  -DenySettingsExcludedPrincipal "<object-id>,<object-id>"

使用参数 “DeploymentResourceGroupName” 指定创建部署堆栈所在的资源组的名称。 如果未指定范围,则使用部署堆栈的范围。

要在管理组范围内应用拒绝设置,请执行以下操作:

New-AzManagementGroupDeploymentStack `
  -Name "<deployment-stack-name>" `
  -Location "<___location>" `
  -TemplateFile "<bicep-file-name>" `
  -ActionOnUnmanage "detachAll" `
  -DenySettingsMode "denyDelete" `
  -DenySettingsExcludedActions "Microsoft.Compute/virtualMachines/write Microsoft.StorageAccounts/delete" `
  -DenySettingsExcludedPrincipal "<object-id>,<object-id>"

使用参数 “DeploymentSubscriptionId ” 指定创建部署堆栈所在的订阅 ID。 如果未指定范围,则使用部署堆栈的范围。

从部署堆栈中分离受管理资源

默认情况下,当不受管理资源不再包含在堆栈的管理范围内时,部署堆栈只分离但不删除不受管理资源。 有关详细信息,请参阅更新部署堆栈

从部署堆栈导出模板

可以将资源从部署堆栈导出到 JSON 输出。 可以通过管道将输出传递给文件。

要在资源组范围内导出部署堆栈,请执行以下操作:

Save-AzResourceGroupDeploymentStack `
   -Name "<deployment-stack-name>" `
   -ResourceGroupName "<resource-group-name>" `

要在订阅范围内导出部署堆栈,请执行以下操作:

Save-AzSubscriptionDeploymentStack `
  -name "<deployment-stack-name>"

要在管理组范围内导出部署堆栈,请执行以下操作:

Save-AzManagementGroupDeploymentStack `
  -Name "<deployment-stack-name>" `
  -ManagementGroupId "<management-group-id>"

后续步骤

要完成 Bicep 部署快速入门,请参阅快速入门:使用 Bicep 创建和部署部署堆栈