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

部署堆栈

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

可以使用 Azure CLI、Azure PowerShell 或 Azure 门户配合 Bicep 文件来创建和更新部署堆栈。 这些 Bicep 文件转换为 ARM JSON 模板,然后由堆栈部署为部署对象。 除了熟悉的部署资源,部署堆栈还提供其他功能,作为这些功能的超集。

Microsoft.Resources/deploymentStacks 是部署堆栈的资源类型。 它由一个主模板组成,可跨范围对其描述的资源执行一对多更新,并能阻止对这些资源进行任何不想要的更改。

在规划部署和确定同一堆栈应包含哪些资源组时,一定要考虑到这些资源的管理生命周期,其中包含创建、更新和删除。 例如,假设你需要为不同资源组范围内的多个应用程序团队预配一些测试虚拟机 (VM)。 这种情况下,可以使用部署堆栈来创建此类测试环境,并通过对部署堆栈进行后续更新来更新测试虚拟机配置。 项目完成后,可能必须移除或删除创建的任何资源,例如测试用的虚拟机。 通过利用部署堆栈,可通过指定合适的删除标记,轻松移除受管理资源。 这种方法更简便,可以在清理环境期间节省时间,因为其只涉及对堆栈资源进行一次更新,而不用一个一个去修改或删除各个资源组范围内的每个测试用虚拟机。

部署堆栈要求 Azure PowerShell 12.0.0 或更高版本,或者 Azure CLI 2.61.0 或更高版本

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

为什么使用部署堆栈?

部署堆栈提供以下优势:

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

已知限制

  • 隐式创建的资源不由部署堆栈管理。 因此,无法进行拒绝分配或清理。
  • 拒绝分配不支持标记。
  • 管理组范围内不支持拒绝分配。 但是,如果部署指向订阅范围,则管理组堆栈支持拒绝分配。
  • 部署堆栈无法删除密钥保管库机密。 如果要从模板中删除密钥保管库机密,请确保也使用分离模式执行部署堆栈更新/删除命令。

已知问题

  • 删除资源组目前会绕过拒绝分配。 在资源组范围内创建部署堆栈时,Bicep 文件不包含资源组的定义。 尽管设置为拒绝分配,但可以删除资源组及其包含的堆栈。 但是,如果在组内的任何资源上处于活动状态,则删除操作将失败。
  • What-if 支持尚不可用。
  • 将限制管理组范围的堆栈不能部署到另一个管理组。 它只能部署到堆栈本身的管理组或子订阅。
  • PowerShell 命令可帮助列出 ActionOnUnmanage 开关的 DeleteResourcesAndResourcesGroups 值。 使用此值时,该命令将拆离受管理资源和资源组。 此值将在下一次更新中移除。 不要使用此值。
  • 在某些情况下,Azure PowerShell 的 New 和 Set 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 文件进行更改。 进行修改后,可以使用以下两个选项来更新部署堆栈:运行更新命令,或重新运行创建命令。

可通过基础结构即代码 (IaC) 设计模式完全控制受管理资源的列表。

使用“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"

改用新命令

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

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 删除不受管理资源,请使用包含以下开关的创建堆栈命令更新堆栈。 有关详细信息,请参阅创建部署堆栈

使用 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}' may not have an accurate list of managed resources. To ensure no resources are accidentally deleted, please check that the managed resource list does not have any additional values. If there is any uncertainty, we recommend redeploying the stack with the same template and parameters as the current iteration. To bypass this warning, please specify the 'BypassStackOutOfSyncError' flag.

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

...
Resources: /subscriptions/9e8db52a-71bc-4871-9007-1117bf304622/resourceGroups/demoRg/providers/Microsoft.Network/virtualNetworks/vnetthmimleef5fwk
           /subscriptions/9e8db52a-71bc-4871-9007-1117bf304622/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 资源(子)。 如果部署堆栈是使用该 Bicep 文件在启用了 DenySettingsApplyToChildScopes 设置的情况下创建的,并且 DenySettingsMode 设置为 DenyWriteAndDelete,则你无法向 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>"

后续步骤

若要完成快速入门,请参阅快速入门:创建部署堆栈