Move a virtual machine from Regional to Zonal availability zone using Azure PowerShell and CLI

This article details using Azure PowerShell and CLI cmdlets to move Azure single instance VMs from regional to zonal availability zones. An availability zone is a physically separate zone in an Azure region. Use availability zones to protect your apps and data from an unlikely failure or loss of an entire data center.

To use an availability zone, create your virtual machine in a supported Azure region.

Prerequisites

Verify the following requirements before you start the move process:

Requirement Description
Subscription permissions Ensure you have Owner access on the subscription containing the resources that you want to move.

Managed identity needs these permissions:
- Permission to write or create resources in user subscription, available with the Contributor role.
- Permission to create role assignments. Typically available with the Owner or User Access Administrator roles, or with a custom role that has the Microsoft.Authorization role assignments or write permission assigned. This permission isn't needed if the data share resource's managed identity is already granted access to the Azure data store.
Learn more about Azure roles.
VM support Review the supported regions.

- Check supported compute, storage, and networking settings.
VM health status The VMs you want to move must be in a healthy state before attempting the zonal move. Ensure that all pending reboots and mandatory updates are complete and the Virtual Machine is working and is in a healthy state before attempting the VM zonal move.

Review PowerShell and CLI requirements

Most move resources operations are the same whether using the Azure portal or PowerShell or CLI, with a couple of exceptions.

Operation Portal PowerShell/CLI
Create a move collection A move collection (a list of all the regional VMs that you're moving) is created automatically. Required identity permissions are assigned in the backend by the portal. You can use PowerShell cmdlets or CLI cmdlets to:
- Assign a managed identity to the collection.
- Add regional VMs to the collection.
Resource move operations Validate steps and validates the User setting changes. Initiate move starts the move process and creates a copy of source VM in the target zone. It also finalizes the move of the newly created VM in the target zone. PowerShell cmdlets or CLI cmdlets to:
- Add regional VMs to the collection
- Resolve dependencies
- Perform the move.
- Commit the move.

Sample values

We use these values in our script examples:

Setting Value
Subscription ID subscription-id
Move Region East US
Resource group (holding metadata for move collection) RegionToZone-DemoMCRG
Move collection name RegionToZone-DemoMC
Location of the move collection eastus2euap
IdentityType SystemAssigned
VM name demoVM-MoveResource
Move Type RegionToZone

Sign in to Azure

Sign in to your Azure subscription with the Connect-AzAccount command and follow the on-screen directions.

Connect-AzAccount –Subscription "<subscription-id>"

Set up the move collection

The MoveCollection object stores metadata and configuration information about the resources you want to move. To set up a move collection, do the following:

  • Create a resource group for the move collection.
  • Register the service provider to the subscription, so that the MoveCollection resource can be created.
  • Create the MoveCollection object with managed identity. For the MoveCollection object to access the subscription in which the Resource Mover service is located, it needs a system-assigned managed identity (formerly known as Managed Service Identity (MSI)) that's trusted by the subscription.
  • Grant access to the Resource Mover subscription for the managed identity.

Create the resource group

Use the following cmdlet to create a resource group for the move collection metadata and configuration information with New-AzResourceGroup. A resource group is a logical container into which Azure resources are deployed and managed.

New-AzResourceGroup -Name "RegionToZone-DemoMCRG" -Location "EastUS"

Output:

The output shows that the managed disk is in the same availability zone as the VM:

ResourceGroupName : RegionToZone-DemoMCRG
Location          : eastus
ProvisioningState : Succeeded
Tags              :
                    Name     Value
                    =======  ========
                    Created  20230908

ResourceId        : /subscriptions/<Subscription-id>/resourceGroups/RegionToZone-DemoMCRG

Register the resource provider

  1. Register the resource provider Microsoft.Migrate, so that the MoveCollection resource can be created, as follows:

    Register-AzResourceProvider -ProviderNamespace Microsoft.Migrate
    
  2. Wait for registration:

    While(((Get-AzResourceProvider -ProviderNamespace Microsoft.Migrate)| where {$_.RegistrationState -eq "Registered" -and $_.ResourceTypes.ResourceTypeName -eq "moveCollections"}|measure).Count -eq 0)
    {
        Start-Sleep -Seconds 5
        Write-Output "Waiting for registration to complete."
    }
    

Create a MoveCollection object

Create a MoveCollection object, and assign a managed identity to it, as follows:

New-AzResourceMoverMoveCollection -Name "RegionToZone-DemoMC"  -ResourceGroupName "RegionToZone-DemoMCRG" -MoveRegion "eastus" -Location "eastus2euap" -IdentityType "SystemAssigned" -MoveType "RegionToZone"

Output:

Etag                                   Location    Name
----                                   --------    ----
"3a00c441-0000-3400-0000-64fac1b30000" eastus2euap RegionToZone-DemoMC

Note

For Regional to zonal move, the MoveType parameter should be set as RegionToZone and MoveRegion parameter should be set as the location where resources undergoing zonal move reside. Ensure that the parameters SourceRegion and TargetRegion are not required and should be set to null.

Grant access to the managed identity

Grant the managed identity access to the Resource Mover subscription as follows. You must be the subscription owner.

  1. Retrieve identity details from the MoveCollection object.

    $moveCollection = Get-AzResourceMoverMoveCollection -Name "RegionToZone-DemoMC" -ResourceGroupName "RegionToZone-DemoMCRG"
    $identityPrincipalId = $moveCollection.IdentityPrincipalId
    
  2. Assign the required roles to the identity so Azure Resource Mover can access your subscription to help move resources. Review the list of required permissions for the move.

    New-AzRoleAssignment -ObjectId $identityPrincipalId -RoleDefinitionName Contributor -Scope "/subscriptions/<subscription-id>""
    New-AzRoleAssignment -ObjectId $identityPrincipalId -RoleDefinitionName "User Access Administrator" -Scope "/subscriptions/<subscription-id>"
    

Add regional VMs to the move collection

Retrieve the IDs for existing source resources that you want to move. Create the destination resource settings object, then add resources to the move collection.

Note

Resources added to a move collection must be in the same subscription but can be in different resource groups.

  1. Create target resource setting object as follows:

    $targetResourceSettingsObj = New-Object Microsoft.Azure.PowerShell.Cmdlets.ResourceMover.Models.Api20230801.VirtualMachineResourceSettings
    $targetResourceSettingsObj.ResourceType = "Microsoft.Compute/virtualMachines"
    $targetResourceSettingsObj.TargetResourceName = "RegionToZone-demoTargetVm"
    $targetResourceSettingsObj.TargetAvailabilityZone = "2"
    

    Output

    ResourceType                      TargetResourceGroupName TargetResourceName        TargetAvailabilitySetId TargetAvailabilityZone TargetVMSize UserManagedIdentity
    ------------                      ----------------------- ------------------        ----------------------- ---------------------- ------------ -------------------
    Microsoft.Compute/virtualMachines                         RegionToZone-demoTargetVm                         2
    
  2. Add resources

    Add-AzResourceMoverMoveResource -ResourceGroupName "RegionToZone-DemoMCRG" -MoveCollectionName "RegionToZone-DemoMC" -SourceId "/subscriptions/<Subscription-id>/resourcegroups/PS-demo-RegionToZone-RG/providers/Microsoft.Compute/virtualMachines/RegionToZone-demoSourceVm" -Name "demoVM-MoveResource" -ResourceSetting $targetResourceSettingsObj
    

    Output

    DependsOn                         : {}
    DependsOnOverride                 : {}
    ErrorsPropertiesCode              :
    ErrorsPropertiesDetail            :
    ErrorsPropertiesMessage           :
    ErrorsPropertiesTarget            :
    ExistingTargetId                  :
    Id                                : /subscriptions/<Subscription-id>/resourceGroups/RegionToZone-DemoMCRG/providers/Microsoft.Migrate/moveCollections/Re
                                        gionToZone-DemoMC/moveResources/demoVM-MoveResource
    IsResolveRequired                 : False
    JobStatusJobName                  :
    JobStatusJobProgress              :
    MoveStatusErrorsPropertiesCode    : DependencyComputationPending
    MoveStatusErrorsPropertiesDetail  : {}
    MoveStatusErrorsPropertiesMessage : The dependency computation is not completed for resource - /subscriptions/<Subscription-id>/resourcegroups/PS-demo-R
                                        egionToZone-RG/providers/Microsoft.Compute/virtualMachines/RegionToZone-demoSourceVm'.
                                            Possible Causes: Dependency computation is pending for resource.
                                            Recommended Action: Validate dependencies to compute the dependencies.
    
    MoveStatusErrorsPropertiesTarget  :
    MoveStatusMoveState               : MovePending
    Name                              : demoVM-MoveResource
    ProvisioningState                 : Succeeded
    ResourceSetting                   : Microsoft.Azure.PowerShell.Cmdlets.ResourceMover.Models.Api20230801.VirtualMachineResourceSettings
    SourceId                          : /subscriptions/<Subscription-id>/resourcegroups/PS-demo-RegionToZone-RG/providers/Microsoft.Compute/virtualMachines/
                                        RegionToZone-demoSourceVm
    SourceResourceSetting             : Microsoft.Azure.PowerShell.Cmdlets.ResourceMover.Models.Api20230801.VirtualMachineResourceSettings
    SystemDataCreatedAt               : 9/8/2023 6:48:11 AM
    SystemDataCreatedBy               : xxxxx@microsoft.com
    SystemDataCreatedByType           : User
    SystemDataLastModifiedAt          : 9/8/2023 6:48:11 AM
    SystemDataLastModifiedBy          : xxxxx@microsoft.com
    SystemDataLastModifiedByType      : User
    TargetId                          :
    Type                              :
    

Modify settings

You can modify destination settings when moving Azure VMs and associated resources. We recommend that you only change destination settings before you validate the move collection.

Settings that you can modify are:

  • Virtual machine settings: Resource group, VM name, VM availability zone, VM SKU, VM key vault, and Disk encryption set.
  • Networking resource settings: For Network interfaces, virtual networks (VNets/), and network security groups/network interfaces, you can either:
    • Use an existing networking resource in the destination region.
    • Create a new resource with a different name.
  • Public IP/Load Balancer: SKU and Zone

Modify settings as follows:

  1. Retrieve the move resource for which you want to edit properties. For example, to retrieve a VM run:

    $moveResourceObj = Get-AzResourceMoverMoveResource -MoveCollectionName " RegionToZone-DemoMCRG " -ResourceGroupName " RegionToZone-DemoMC " -Name "PSDemoVM"
    
  2. Copy the resource setting to a target resource setting object.

    $TargetResourceSettingObj = $moveResourceObj.ResourceSetting
    
  3. Set the parameter in the target resource setting object. For example, to change the name of the destination VM:

    $TargetResourceSettingObj.TargetResourceName="PSDemoVM-target"
    
  4. Update the move resource destination settings. In this example, we change the name of the VM from PSDemoVM to PSDemoVMTarget.

    Update-AzResourceMoverMoveResource -ResourceGroupName " RegionToZone-DemoMCRG " -MoveCollectionName " RegionToZone-DemoMC -SourceId "/subscriptions/<Subscription-d>/resourceGroups/PSDemoRM/providers/Microsoft.Compute/virtualMachines/PSDemoVM" -Name "PSDemoVM" -ResourceSetting $TargetResourceSettingObj
    

Resolve dependencies

Check whether the regional VMs you added have any dependencies on other resources, and add as needed.

  1. Resolve dependencies as follows:

    Resolve-AzResourceMoverMoveCollectionDependency -ResourceGroupName "RegionToZone-DemoMCRG" -MoveCollectionName "RegionToZone-DemoMC"
    

    Output (when dependencies exist)

    AdditionalInfo :
    Code           :
    Detail         :
    EndTime        : 
    EndTime        : 9/8/2023 6:52:14 AM
    
    Id             : /subscriptions/<Subscription-id>/resourceGroups/RegionToZone-DemoMCRG/providers/Microsoft.Migrate/moveCollections/RegionToZone-DemoMC/operations/bc68354b-ec1f-44cb-92ab-fb3b4ad90229
    Message        :
    Name           : bc68354b-ec1f-44cb-92ab-fb3b4ad90229
    Property       : Microsoft.Azure.PowerShell.Cmdlets.ResourceMover.Models.Any
    StartTime      : 9/8/2023 6:51:50 AM
    Status         : Succeeded
    
  2. To get a list of resources added to the move collection:

    $list = Get-AzResourceMoverMoveResource -ResourceGroupName "RegionToZone-DemoMCRG" -MoveCollectionName "RegionToZone-DemoMC" $list.Name
    

    Output:

    demoVM-MoveResource
    mr_regiontozone-demosourcevm661_d6f18900-3b87-4fb5-9bdf-12da2f9fb185
    mr_regiontozone-demosourcevm-vnet_d8536bf5-2d5f-4778-9650-32d0570bc41a
    mr_regiontozone-demosourcevm-ip_6af03f1f-eae8-4541-83f5-97a2506cfc3e
    mr_regiontozone-demosourcevm-nsg_98d68420-d7ff-4e2d-b758-25a6df80fca7
    mr_nrms-timkbo3hy3nnmregiontozone-demosourcevm-vnet_f474c880-4823-4ed3-b761-96df6500f6a3
    
  3. To remove resources from the resource collection, follow these instructions.

Availability Zones VM SKU, Quota and Capacity validations

Azure provides recommendations when the selected Availability Zone doesn't have the virtual machine SKU, or when there is not enough Quota or Capacity available. Here are some examples of these recommendations and the actions that should be taken if the virtual machine SKU is not available.

VM SKU not available

When the source virtual machine size Standard_DC1ds_v3 isn't available in the selected availability zone 1.

Recommended Action: Choose a different virtual machine size in the same availability zone or select a different availability zone with corresponding recommended VM size.

Recommendations:

  • SKU: Standard_DC1ds_v3, Zones: [ 2 ]
  • SKU: Standard_DC2ds_v3, Zones: [ 2 ]
  • SKU: Standard_DC4ds_v3, Zones: [ 2 ]
  • SKU: Standard_DC1s_v3, Zones: [ 2 ]
  • SKU: Standard_D2ds_v5, Zones: [ 2, 3 ]
  • SKU: Standard_D2as_v4, Zones: [ 1, 2, 3 ]
  • SKU: Standard_D2s_v3, Zones: [ 1, 2, 3 ]
  • SKU: Standard_D2as_v5, Zones: [ 1, 2, 3 ]
  • SKU: Standard_D2s_v5, Zones: [ 2, 3 ]

Capacity recommendations

Capacity recommendations for the current selection virtual machine size Standard_DC1ds_v3 in the selected availability zone 1.

Recommended Action: To increase the likelihood of a successful deployment, Azure has identified other recommended virtual machine sizes and zones. To deploy seamlessly, choose a different VM size in the same availability zone or a different availability zone with corresponding virtual machine size.

Recommendations:

  • SKU: Standard_DC1ds_v3, Zones: [ 2 ]
  • SKU: Standard_DC2ds_v3, Zones: [ 2 ]
  • SKU: Standard_DC4ds_v3, Zones: [ 2 ]
  • SKU: Standard_DC1s_v3, Zones: [ 2 ]
  • SKU: Standard_D2ds_v5, Zones: [ 2, 3 ]
  • SKU: Standard_D2as_v4, Zones: [ 1, 2, 3 ]
  • SKU: Standard_D2s_v3, Zones: [ 1, 2, 3 ]
  • SKU: Standard_D2as_v5, Zones: [ 1, 2, 3 ]
  • SKU: Standard_D2s_v5, Zones: [ 2, 3 ]

Address the recommendations

To address the situations where the VM SKU is not found or there is a capacity issue, update the move resource and then run resolve again. Here is an example for reference:

  1. Update virtual machine move resource object to new Zone or SKU as per the recommendations.

    $targetResourceSettingsObj.TargetVmSize = "Standard_DC1ds_v3"
    $targetResourceSettingsObj.TargetAvailabilityZone = "3"
    
  2. Update virtual machine move resource

    Add-AzResourceMoverMoveResource -ResourceGroupName "RegionToZone-DemoMCRG" -MoveCollectionName "RegionToZone-DemoMC" -SourceId "/subscriptions/<Subscription ID>/resourceGroups/<Resource Group Name>/providers/Microsoft.Compute/virtualMachines/vmtwo" -Name "demoVM-MoveResource2" -ResourceSetting $targetResourceSettingsObj
    
  3. Run resolve again

    Resolve-AzResourceMoverMoveCollectionDependency -ResourceGroupName "RegionToZone-DemoMCRG" -MoveCollectionName "RegionToZone-DemoMC"

Insufficient Quota

Selected virtual machine can't be moved to availability zone due to insufficient quota.

Recommended Action: In-sufficient quota found. Refer to link and contact support.

Initiate move of VM resources

Invoke-AzResourceMoverInitiateMove -ResourceGroupName "RegionToZone-DemoMCRG" -MoveCollectionName "RegionToZone-DemoMC" -MoveResource $("demoVM-MoveResource") -MoveResourceInputType "MoveResourceId"

Output

AdditionalInfo :
Code           :
Detail         :
EndTime        : 9/8/2023 7:07:58 AM
Id             : /subscriptions/<Subscription-id>/resourceGroups/RegionToZone-DemoMCRG/providers/Microsoft.Migrate/moveCollections/RegionToZone-DemoMC/o
                 perations/d3e06ac3-a961-4045-8301-aee7f6911160
Message        :
Name           : d3e06ac3-a961-4045-8301-aee7f6911160
Property       : Microsoft.Azure.PowerShell.Cmdlets.ResourceMover.Models.Any
StartTime      : 9/8/2023 7:01:31 AM
Status         : Succeeded

Commit

After the initial move, you must commit the move or discard it. Commit completes the move to the target region.

Commit the move as follows:

Invoke-AzResourceMover-VMZonalMoveCommit -ResourceGroupName "RG-MoveCollection-demoRMS" -MoveCollectionName "PS-centralus-westcentralus-demoRMS" -MoveResource $('psdemovm111', 'PSDemoRM-vnet','PSDemoVM-nsg', ‘PSDemoVM’) -MoveResourceInputType "MoveResourceId"

Output:

AdditionalInfo : 
Code           : 
Detail         : 
EndTime        : 9/22/2023 5:26:55 AM 
Id             : /subscriptions/e80eb9fa-c996-4435-aa32-5af6f3d3077c/resourceGroups/RegionToZone-DemoMCRG/providers/Microsoft.Migrate/moveCollections/RegionToZone-DemoMC/operations/35dd1d93-ba70-4dc9-a17f-7d8ba48678d8 
Message        : 
Name           : 35dd1d93-ba70-4dc9-a17f-7d8ba48678d8 
Property       : Microsoft.Azure.PowerShell.Cmdlets.ResourceMover.Models.Any 
StartTime      : 9/22/2023 5:26:54 AM 
Status         : Succeeded 

Remove a resource

You can remove a single resource or multiple resources from a MoveCollection using the following cmdlets:

  1. Get a list of the move resources that are added to the move collection: $list = Get-AzResourceMoverMoveResource -ResourceGroupName "<MoveCollectionResourceGroupName>" -MoveCollectionName "<MoveCollectionName>"

  2. Remove the move resources you found: Invoke-AzResourceMoverBulkRemove -ResourceGroupName "<MoveCollectionResourceGroupName>" -MoveCollectionName "<MoveCollectionName>" -MoveResource $($list.Name)

  3. Remove the move collection: Remove-AzResourceMoverMoveCollection -ResourceGroupName "<MoveCollectionResourceGroupName>" -MoveCollectionName "<MoveCollectionName>"

Note

If you observe managed identities authorization issues, re-enable the managed identities access by following these steps again.

Delete source regional VMs

After you commit the move and verify that the resources work as expected in the target region, you can delete each source resource using:

Next steps

Learn how to move single instance Azure VMs from regional to zonal configuration via portal.