Posts Moving Managed Disks to different Azure Region
Post
Cancel

Moving Managed Disks to different Azure Region

Moving Managed Disks to different Azure Region - AzureIs.Fun

Migrating Azure Resources between Resource Groups, Subscriptions, Tenants, and Regions was significantly improved recently. However, some things are still problematic. I am not going to try to summarize it all in this one article. Instead, we will solve one particular problem - migration of Managed Disk to different Azure Region.

There are a few ways how this can be done. The most common scenario is migrating disks with the VM, which you can easily do with the Azure Resource Mover. Moving VM will also move the attached disks.

However, Resource Mover can’t move disks as resources, only as part of a VM. So if you need to be more flexible and move VMs without a network or you need to move a single unattached disk, Resource Moves is not your friend. Service is constantly improving and this might change in the future. You can find the up to date resource support matrix HERE.

Moving Azure Disk to a different Azure Region

One of the ways to do migrate the disk is to do the following steps:

  1. Move disk to different subscription if needed
  2. Export managed disk as VHD
  3. Move VHD file to a temporary storage account container that is in the target Azure Region
  4. Convert it back to a Managed Disk
  5. Attach disk to VM or build a VM from the OS disk
  6. Clean up old resources

Let’s do this together. Naturally, with Azure PowerShell.

Here we should define some variables first:

1
2
3
4
5
6
7
8
$SourceSubscriptionName = "Sub1"
$TargetSubscriptionName = "Sub2"

$TargetResourceGroupName = "RG2"

$TargetLocationName = "West US 2"

$DiskName = "VM01_disk1"

And then login, set context and validate input:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Connect-AzAccount

$SourceSubscription = Get-AzSubscription -SubscriptionName $SourceSubscriptionName
$TargetSubscription = Get-AzSubscription -SubscriptionName $TargetSubscriptionName

Set-AzContext -SubscriptionObject $SourceSubscription

#Get disk information:
$SourceDisk = Get-AzDisk -DiskName $DiskName

Get Target Location:
$TargetLocation =  (Get-AzLocation | Where-Object { $_.DisplayName -eq $TargetLocationName }).Location

#Validate if target Resource Groups exists and if not create it:
if (-not (Get-AzResourceGroup -Name $TargetResourceGroupName -ErrorAction SilentlyContinue)) {
    New-AzResourceGroup -Name $TargetResourceGroupName -Location $TargetLocation -Force | Out-Null
}

Move resource to a different subscription

1
2
3
4
5
6
7
8
9
10
If ($SourceSubscription.TenantId -eq $TargetSubscription.TenantId) {

    Move-AzResource -DestinationResourceGroupName $TargetResourceGroupName -DestinationSubscriptionId $TargetSubscription.Id -ResourceId $SourceDisk.Id

}

Set-AzContext -SubscriptionObject $TargetSubscription

#Get disk information from the new subscription:
$SourceDisk = Get-AzDisk -DiskName $DiskName

Create a temporary Storage Account and Container in target Azure Region

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$storageAccountParams = @{
    ResourceGroupName = $TargetResourceGroupName
    Location          = $TargetLocation
    SkuName           = 'Standard_LRS'
    Name              = 'satemp{0:yyyyMMddHHmmssff}' -f (Get-Date)
}; $targetStorage = New-AzStorageAccount @storageAccountParams


$storageContextParams = @{
    StorageAccountName = $targetStorage.StorageAccountName
    StorageAccountKey  = (
        Get-AzStorageAccountKey -ResourceGroupName $targetStorage.ResourceGroupName -Name $targetStorage.StorageAccountName)[0].Value
}; $storageContext = New-AzStorageContext @storageContextParams

New-AzStorageContainer -Name vhd -Context $storageContext | Out-Null

Export Managed Disk

1
2
3
4
5
6
7
#Generate SAS token with duration 1 hour and Read access
$osDiskAccessParams = @{
    ResourceGroupName = $TargetResourceGroupName
    DiskName          = $SourceDisk.Name
    DurationInSecond  = 3600
    Access            = 'Read'
}; $osDiskSAS = Grant-AzDiskAccess @osDiskAccessParams

Copy disk to Storage Account in new Azure Region

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$blobCopyParams = @{
        AbsoluteUri   = $osDiskSAS.AccessSAS
        DestContainer = 'vhd'
        DestContext   = $storageContext
        DestBlob      = ('{0}_Disk.vhd' -f $Disk.Name) #Define your disk name here
}; Start-AzStorageBlobCopy @blobCopyParams | Out-Null

#Because this action is going to take some time, let's monitor the progress:

do {
    Start-Sleep -Seconds 30
    $copyState = Get-AzStorageBlobCopyState -Blob $blobCopyParams.DestBlob -Container 'vhd' -Context $storageContext
    $progress = [Math]::Round((($copyState.BytesCopied / $copyState.TotalBytes) * 100))
    Write-Host ('WAITING: {0:HH:mm:ss} - Waiting for the {1} blob copy process to complete ({2} %)' -f (Get-Date), $DestinationBlob, $progress) -ForegroundColor Yellow
} until ($copyState.Status -ne [Microsoft.Azure.Storage.Blob.CopyStatus]::Pending)

Disk copy can also be performed with AZCopy.

Create new Managed Disk from VHD in Storage Account

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
$disksDetails = @{ }
$disksDetails.Add(($SourceDisk.Name),
    [PSCustomObject]@{
        SkuName = $SourceDisk.Sku.Name
        Caching = "ReadWrite"
    }
)

$newDiskConfigParams = @{
    CreateOption     = 'Import'
    StorageAccountId = $targetStorage.Id
    SkuName          = ($disksDetails[($SourceDisk.Name)]).SkuName
    OsType           = "Windows"
    Location         = $TargetLocation
    SourceUri        = 'https://{0}.blob.core.windows.net/vhd/{1}_Disk.vhd' -f $targetStorage.StorageAccountName, $SourceDisk.Name
}; $newDiskConfig = New-AzDiskConfig @newDiskConfigParams

$newDiskParams = @{
    Disk              = $newDiskConfig
    ResourceGroupName = $TargetResourceGroupName
    DiskName          = 'NewDisk_{0}' -f $SourceDisk.Name
}; $newOsDisk = New-AzDisk @newDiskParams

Using the disk

Now that we completed the migration, the two last steps are to create a VM or attach it to an existing VM and test it out. The original disk still exists in the source Subscription, and you can now clean that up.

Conclusion

With many different types of subscription offers and various dependencies for each resource type, migrating resources can sometimes be tricky. I hope this guide was helpful.

Top 100 Azure Blogs

AzureIs.Fun blog made it to the list of Top 100 Microsoft Azure blogs. Yeeey. I want to thank you, my readers, for sticking around.

I started this blog a year ago. I had so many great article ideas that I wanted to write about. But I was so overwhelmed by work and other community activities that I struggled to keep it up. I recently decided not to postpone blogging because I don’t have time to write those BIG idea articles and I started writing shorter posts more often :-)


Thank you for reading and all the feedback.

Vukašin Terzić

Updated Mar 14, 2021 2021-03-14T09:53:58+01:00
This post is licensed under CC BY 4.0