다음을 통해 공유

将 Azure 资源移到新的资源组或订阅

本文介绍如何在同一订阅或不同订阅中的资源组之间移动 Azure 资源。 如果移动涉及不同的订阅,则这两个订阅都必须属于同一Microsoft Entra ID 租户。 可以使用 Azure 门户Azure PowerShellAzure CLIREST APIPython 等工具来移动资源。

在移动作期间,源资源组和目标资源组均处于锁定状态。 移动正在进行时,无法创建、删除或更新这些资源组中的资源。 但是,现有资源仍然完全正常运行。 例如,如果将虚拟机从一个资源组移动到另一个资源组,则无法在移动期间删除虚拟机或修改其属性(如其大小)。 尽管存在这种限制,但虚拟机继续正常运行,依赖虚拟机的服务不会经历任何停机。 锁定装置最多可以持续四个小时。 大多数移动完成得更快,锁被相应地释放。

移动请求中只应指定顶级(父级)资源。 子资源随父资源自动移动,但无法独立移动。 例如,当移动父资源Microsoft.Compute/virtualMachines时,其子资源Microsoft.Compute/virtualMachines/extensions将随之移动。 但是,你无法单独地移动子资源。

移动资源时会保留它与子资源的依赖关系,但与其他资源的依赖关系可能会中断,因此可能需要重新配置。 移动资源只会更改其关联的资源组,并且不会更改资源的物理区域。

注意

如果源、目标资源组或订阅上存在只读锁,则无法移动 Azure 资源。

更改的资源 ID

移动资源时,会更改其资源 ID。 资源 ID 的标准格式为 /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}。 将资源移到新的资源组或订阅时,会更改该路径中的一个或多个值。

如果在任意位置使用资源 ID,请更改该值。 例如,如果门户中有引用资源 ID 的 自定义仪表板 ,请更新该值。 查找需要针对新资源 ID 进行更新的任何脚本或模板。

移动资源前需查看的清单

移动资源之前,需要执行一些重要步骤。 如果验证这些条件,可以避免错误。

  1. 源订阅和目标订阅必须处于活动状态。 如果在启用禁用的帐户时遇到问题, 请创建 Azure 支持请求。 选择“订阅管理” 作为问题类型。

  2. 源订阅与目标订阅必须在同一个 Microsoft Entra 租户中。 使用 Azure CLI 或 PowerShell 检查这两个订阅是否具有相同的租户 ID。

    az account show --subscription <your-source-subscription> --query tenantId
    az account show --subscription <your-destination-subscription> --query tenantId
    

    如果源订阅和目标订阅的租户 ID 不匹配,请使用以下方法来协调它们:

  3. 要移动的资源必须支持移动操作。 有关支持移动操作的资源列表,请参阅 用于移动操作的 Azure 资源类型

  4. 某些服务在移动资源时有特定的限制或要求。 在移动这些服务中的资源之前,请检查以下移动指南:

  5. 要移动资源的目标订阅必须注册相应的资源提供程序。 如果不是,则会收到一条错误信息,指出 订阅未登记注册资源类型。 将资源移动到新订阅时,可能会看到此错误,但以前未在订阅中使用资源类型。

    要获取注册状态,请按以下步骤操作:

    az account set -s <destination-subscription-name-or-id>
    az provider list --query "[].{Provider:namespace, Status:registrationState}" --out table
    

    注册资源提供程序:

    az provider register --namespace Microsoft.Batch
    
  6. 在开始移动操作之前,请检查您要向其移动资源的订阅的配额。 验证是否可以请求增加配额,以致目标订阅超出其配额限制。 有关限制以及如何请求增加的详细指南,请参阅 Azure 订阅和服务限制、配额和约束

  7. 移动资源的帐户至少需要具备下列权限:

    • 在源资源组: Microsoft.Resources/subscriptions/resourceGroups/moveResources/action
    • 在目标资源组: Microsoft.Resources/subscriptions/resourceGroups/write
  8. 如果移动具有活动 Azure 角色分配的资源(或其具有相同分配的子资源),则角色分配不会移动并将变成孤立的。 移动后必须再次创建角色分配。 尽管系统会自动删除孤立的角色分配,但建议在移动之前将其删除。

    若要详细了解如何管理角色分配,请参阅 列出 Azure 角色分配分配 Azure 角色

  9. 若要跨订阅移动,则资源及其依赖资源必须位于同一资源组中,并且必须一起移动。 例如,具有托管磁盘的虚拟机需要将虚拟机、托管磁盘和其他依赖资源一起移动。

    如果要将资源移到新订阅,请检查资源是否具有任何依赖资源,以及资源是否位于同一资源组中。 如果资源不在同一资源组中,请检查是否可以将它们合并到同一资源组中。 如果可以,可以使用跨资源组执行一次移动作,将所有资源合并到同一资源组中。

    有关详细信息,请参阅跨订阅移动方案

跨订阅迁移的场景

将资源从一个订阅移到另一个订阅是一个三步的过程。 为了说明这些步骤,下图只描述一个依赖资源:

显示跨订阅移动资源的三步过程的示意图。

  • 步骤 1:如果依赖资源分布在不同的资源组中,请先将它们移到一个资源组。
  • 步骤 2:将资源和依赖资源一起从源订阅移到目标订阅。
  • 步骤 3:也可将依赖资源重新分布到目标订阅中的不同资源组。

移动资源

使用 Azure 门户

  1. 若要移动资源,请选择包含那些资源的资源组。

  2. 选择要移动的资源。 若要移动所有资源,请选中列表顶部的复选框。 或者,分别选择各个资源。

    Azure 门户的屏幕截图,其中显示了要移动的资源的选择。

  3. 选择“移动”按钮

    Azure 门户的屏幕截图,其中显示了带有三个选项的“移动”按钮。

    此按钮提供了三个选项:

    • 移动到新的资源组。
    • 移动到新的订阅。
  1. 如果要将资源移动到新的资源组或订阅,请选择。

  2. 源资源组自动设置。 指定目标资源组。 如果要移动到新订阅,请指定此选项。 选择“下一页”。

    Azure 门户的屏幕截图,其中显示了用户指定要执行移动操作的目标资源组。

  3. 门户验证资源是否可移动。 等待验证完成。

Azure 门户的屏幕截图,其中显示了移动操作的验证过程。

  1. 验证成功完成后,选择“下一步”。

  2. 确认需要更新这些资源的工具和脚本。 若要开始移动资源,请选择“移动”。

Azure 门户的屏幕截图,其中显示了用户确认需要在开始移动操作之前更新工具和脚本。

  1. Azure 门户会在移动完成后通知你。

Azure 门户的屏幕截图,其中显示了包含移动操作结果的通知。

使用 Azure CLI

验证

若要在不实时移动资源的情况下测试移动方案,请使用 az resource invoke-action 命令。 仅当需要对结果进行建模而不执行时,才使用此命令。 要运行此操作,您需要源资源组、目标资源组和每个您要移动的资源的资源 ID。

请使用 \" 转义请求正文中的双引号。

az resource invoke-action --action validateMoveResources \
  --ids "/subscriptions/{subscription-id}/resourceGroups/{source-rg}" \
  --request-body "{  \"resources\": [\"/subscriptions/{subscription-id}/resourceGroups/{source-rg}/providers/{resource-provider}/{resource-type}/{resource-name}\", \"/subscriptions/{subscription-id}/resourceGroups/{source-rg}/providers/{resource-provider}/{resource-type}/{resource-name}\", \"/subscriptions/{subscription-id}/resourceGroups/{source-rg}/providers/{resource-provider}/{resource-type}/{resource-name}\"],\"targetResourceGroup\":\"/subscriptions/{subscription-id}/resourceGroups/{destination-rg}\" }" 

如果验证通过,则会看到:

{} Finished .. 

如果验证失败,则会看到一条错误消息,说明无法移动资源的原因。

移动

若要将现有资源移到另一个资源组或订阅,请使用 az resource move 该命令。 在 --ids 参数中,提供要移动的资源 ID 的空格分隔列表。

以下命令演示如何将多个资源移到新的资源组。 他们在 Bash 终端或 Azure PowerShell 控制台中使用 Azure CLI。 若要将资源移到新订阅,请提供 --destination-subscription-id 参数。

webapp=$(az resource show -g OldRG -n ExampleSite --resource-type "Microsoft.Web/sites" --query id --output tsv)
plan=$(az resource show -g OldRG -n ExamplePlan --resource-type "Microsoft.Web/serverfarms" --query id --output tsv)
az resource move --destination-group newgroup --ids $webapp $plan

使用 Azure PowerShell

验证

若要在不实时移动资源的情况下测试移动方案,请使用 Invoke-AzResourceAction Azure PowerShell 中的命令。 仅当需要对结果进行建模而无需实际执行时,才使用此命令。

$sourceName = "sourceRG"
$destinationName = "destinationRG"
$resourcesToMove = @("app1", "app2")

$sourceResourceGroup = Get-AzResourceGroup -Name $sourceName
$destinationResourceGroup = Get-AzResourceGroup -Name $destinationName

$resources = Get-AzResource -ResourceGroupName $sourceName | Where-Object { $_.Name -in $resourcesToMove }

Invoke-AzResourceAction -Action validateMoveResources `
  -ResourceId $sourceResourceGroup.ResourceId `
  -Parameters @{
  resources = $resources.ResourceId;  # Wrap in an @() array if providing a single resource ID string.
  targetResourceGroup = $destinationResourceGroup.ResourceId
  }

如果验证成功,则不会显示输出。 但是,如果验证失败,错误消息将解释为何无法移动资源。

移动

要将现有资源移到另一个资源组或订阅,请使用 Move-AzResource 命令。 下面的示例演示了如何将多个资源移动到新的资源组。

$sourceName = "sourceRG"
$destinationName = "destinationRG"
$resourcesToMove = @("app1", "app2")

$resources = Get-AzResource -ResourceGroupName $sourceName | Where-Object { $_.Name -in $resourcesToMove }

Move-AzResource -DestinationResourceGroupName $destinationName -ResourceId $resources.ResourceId

若要移到新订阅,请包含 DestinationSubscriptionId 参数的值。

使用 Python

验证

若要在不实时移动资源的情况下测试移动方案,请使用 ResourceManagementClient.resources.begin_validate_move_resources 此方法。 仅在需要对结果进行建模而无需实施具体措施时,才使用此方法。

import os
from azure.identity import AzureCliCredential
from azure.mgmt.resource import ResourceManagementClient

credential = AzureCliCredential()
subscription_id = os.environ["AZURE_SUBSCRIPTION_ID"]

resource_client = ResourceManagementClient(credential, subscription_id)

source_name = "sourceRG"
destination_name = "destinationRG"
resources_to_move = ["app1", "app2"]

destination_resource_group = resource_client.resource_groups.get(destination_name)

resources = [
  resource for resource in resource_client.resources.list_by_resource_group(source_name)
  if resource.name in resources_to_move
]

resource_ids = [resource.id for resource in resources]

validate_move_resources_result = resource_client.resources.begin_validate_move_resources(
  source_name,
  {
  "resources": resource_ids,
  "target_resource_group": destination_resource_group.id
  }
).result()

print("Validate move resources result: {}".format(validate_move_resources_result))

如果验证成功,则不会显示输出。 但是,如果验证失败,错误消息将解释为何无法移动资源。

移动

若要将现有资源移到另一个资源组或订阅,请使用 ResourceManagementClient.resources.begin_move_resources Python 中的方法。 下面的示例演示了如何将多个资源移动到新的资源组。

import os
from azure.identity import AzureCliCredential
from azure.mgmt.resource import ResourceManagementClient

credential = AzureCliCredential()
subscription_id = os.environ["AZURE_SUBSCRIPTION_ID"]

resource_client = ResourceManagementClient(credential, subscription_id)

source_name = "sourceRG"
destination_name = "destinationRG"
resources_to_move = ["app1", "app2"]

destination_resource_group = resource_client.resource_groups.get(destination_name)

resources = [
  resource for resource in resource_client.resources.list_by_resource_group(source_name)
  if resource.name in resources_to_move
]

resource_ids = [resource.id for resource in resources]

resource_client.resources.begin_move_resources(
  source_name,
  {
  "resources": resource_ids,
  "target_resource_group": destination_resource_group.id
  }
)

使用 REST API

验证

validate move operation 操作无需实际移动资源即可测试移动场景。 使用此操作来检查移动是否能成功。 发送移动请求时会自动调用验证。 仅当需要对结果进行建模而不执行后续操作时,才使用此操作。 若要运行此操作,需要:

  • 源资源组的名称
  • 目标资源组的资源 ID
  • 要移动的每个资源的资源 ID
  • 你的帐户的访问令牌

发送以下请求:

POST https://management.chinacloudapi.cn/subscriptions/<subscription-id>/resourceGroups/<source-group>/validateMoveResources?api-version=2019-05-10
Authorization: Bearer <access-token>
Content-type: application/json

包含请求正文:

{
 "resources": ["<resource-id-1>", "<resource-id-2>"],
 "targetResourceGroup": "/subscriptions/<subscription-id>/resourceGroups/<target-group>"
}

如果请求格式正确,则操作将返回:

Response Code: 202
cache-control: no-cache
pragma: no-cache
expires: -1
location: https://management.chinacloudapi.cn/subscriptions/<subscription-id>/operationresults/<operation-id>?api-version=2018-02-01
retry-after: 15
...

202 状态代码指示已接受验证请求,但尚未确定移动作是否成功。 location 值包含用于检查长时间运行操作的状态的 URL。

若要检查状态,请发送以下请求:

GET <location-url>
Authorization: Bearer <access-token>

当操作运行时,您会继续收到202状态代码。 请等待 retry-after 值中所示的秒数,然后重试。 如果移动验证成功,则会收到 204 状态代码。 如果移动验证失败,将收到类似于以下内容的错误消息:

{"error":{"code":"ResourceMoveProviderValidationFailed","message":"<message>"...}}

移动

若要将现有资源移到另一资源组或订阅,请使用Move resources操作。

POST https://management.chinacloudapi.cn/subscriptions/{source-subscription-id}/resourcegroups/{source-resource-group-name}/moveResources?api-version={api-version}

在请求正文中指定要移动的目标资源组和资源。

{
 "resources": ["<resource-id-1>", "<resource-id-2>"],
 "targetResourceGroup": "/subscriptions/<subscription-id>/resourceGroups/<target-group>"
}

常见问题解答

我的资源移动过程通常只需要几分钟,但这次运行已经接近一小时。 有问题吗?

移动资源是一个具有不同阶段的复杂操作。 它不仅仅涉及你尝试移动的资源的资源提供程序。 Azure 资源管理器允许移动操作完成所需的四小时,因为资源提供程序之间存在依赖关系。 此持续时间可让他们有时间从暂时性问题中恢复。 如果您的移动请求是在四小时的时间段内,操作会一直尝试完成,并且可能会成功。 此作在此期间锁定源和目标资源组,以避免一致性问题。

为什么在资源移动过程中,我的资源组会锁定四个小时?

  • 迁移操作最多可持续四个小时。 此作在此期间锁定源和目标资源组,以防止修改它们。

  • 移动请求中有两个阶段。 在第一阶段期间资源会被移动,依赖于这些被移动资源的资源提供程序会在第二阶段收到通知。 当资源提供程序在任一阶段失败时,资源组可能会被锁定四个小时。 资源管理器在移动操作期间重新启动任何已失败的步骤。

  • 如果资源在四小时内未移动,资源管理器会解锁这两个资源组。 成功移动的资源位于目标资源组中。 无法移动的资源保留在源资源组中。

在资源移动期间锁定的源和目标资源组有何影响?

该锁可防止删除任一资源组。 该锁还阻止你创建新资源、删除资源或更新每个资源组中的资源属性(例如,更改虚拟机的大小)。

下图显示了在尝试删除属于正在进行的移动过程中的资源组时,Azure 门户中的错误消息:

Azure 门户的屏幕截图,其中显示了尝试删除正在进行的移动操作中涉及的资源组时出现的错误消息。

在上图中,虚拟机资源属于当前正在进行移动操作的资源组(“TestB”)。 尝试更新虚拟机的属性(例如其大小),Azure 门户将返回一条错误消息。 发生此错误的原因是资源组在移动期间被锁定,从而防止其资源被修改。

当用户尝试更新虚拟机的属性(虚拟机大小)时,Azure 门户的屏幕截图显示错误消息。

此外,源与目标资源组无法在资源迁移操作期间同时参与其他迁移操作。 例如,如果要将资源从资源组 A 移到资源组 B,则资源组 A 和资源组 B 不能同时参与另一个移动作。 无法同时将资源移入或移出资源组 C。此限制可防止在移动过程中因多个冲突操作而锁定资源组。

错误代码“MissingMoveDependentResources”的含义是什么?

移动资源时,其依赖资源必须存在于目标资源组或订阅中,或包含在移动请求中。 当依赖资源不符合此要求时,会收到 MissingMoveDependentResources 错误代码。 错误消息提供有关移动请求中需要包括的依赖资源的详细信息。

例如,移动某个虚拟机可能需要移动具有三个不同资源提供程序的七个资源类型。 这些资源提供程序和类型为:

  • Microsoft.Compute

    • virtualMachines
    • disks
  • Microsoft.Network

    • networkInterfaces
    • publicIPAddresses
    • networkSecurityGroups
    • virtualNetworks
  • Microsoft.Storage

    • storageAccounts

另一个常见示例涉及移动虚拟网络,其中可能需要移动与该虚拟网络关联的多个其他资源。 移动请求可能需要移动公共 IP 地址、路由表、虚拟网络网关、网络安全组和其他资源。 虚拟网络网关应与其虚拟网络位于同一资源组中,因为它们无法单独移动。

错误代码“RequestDisallowedByPolicy”的含义是什么?

资源管理器在尝试移动之前验证移动请求。 此验证包括检查为移动中涉及的资源定义的策略。 例如,尝试移动密钥保管库时,验证失败,但组织有一个策略来拒绝在目标资源组中创建密钥保管库。 返回的错误代码为 RequestDisallowedByPolicy。

有关策略的详细信息,请参阅什么是 Azure Policy?

为什么无法在 Azure 中移动某些资源?

并非所有 Azure 资源都允许移动操作。

在一次操作中可以移动多少个资源?

尽可能将较大的移动拆分到不同的移动操作中。 在一次操作中有 800 多项资源时,资源管理器会立即返回错误。 但是,由于超时,移动少于 800 个资源也可能会失败。

资源未处于“成功”状态的错误的含义是什么?

收到一条错误消息,指出由于资源未处于 “成功 ”状态而无法移动资源,可能是因为依赖资源正在阻止移动。 通常,错误代码为 MoveCannotProceedWithResourcesNotInSucceededState

如果源或目标资源组包含虚拟网络,则移动期间会检查依赖于该虚拟网络的所有资源的状态。 此检查包括直接或间接依赖网络的资源。 如果任何资源未处于成功状态,移动操作将被阻止。 例如,如果虚拟机使用的虚拟网络未报告成功状态,则会阻止虚拟机的移动。 即使虚拟机不是被移动的资源之一,移动也会受到阻碍。 即使虚拟机不在源或目标资源组中,也会阻止移动。

若要解决此问题,请将资源移至未包含虚拟网络的资源组,或 联系支持人员

是否可以将资源组移动到其他订阅?

否,你无法将资源组移动到新订阅。 但是,可以将资源组中的所有资源移到另一个订阅中的资源组。 标记、角色分配和策略等设置不会自动从原始资源组传输到目标资源组。 需要手动将这些设置应用到新的资源组。

后续步骤

若要验证哪些 Azure 资源支持移动操作,请参阅 资源的移动操作支持