Last Update: Sep 04, 2024 | Published: Jul 28, 2016
In this “how to” article, I’m going to show you how you can quickly and easily move Classic / Service Management / SM Azure IaaS virtual machine deployments to Azure Resource Manager / ARM in another subscription. For example, you can migrate virtual machines and their dependencies from direct/Open/EA Azure subscriptions to Cloud Solution Provider (CSP) subscriptions.
If you want to migrate Azure classic virtual machines to ARM in the same subscription, then have a look at Migrating Azure VMs from Classic Service Management to Resource Manager on Petri IT Knowledgebase.
If you were unsure after the recent Microsoft Worldwide Partner Conference (WPC), then let me be clear; CSP is Microsoft’s preferred way to sell cloud services (and more) via the Microsoft Partner Network. CSP offers quite a bit for partners and customers, because it gives them the billing the want/expect, with a built-in support program, and true OPEX flexibility.
The first challenge with Azure in CSP is that, unlike every other channel, it supports only Azure V2, otherwise known as Azure Resource Manager or ARM. The vast majority of previously deployed solutions are based on the older Azure V1, or Service Management or Classic resources. The second issue with CSP is that Microsoft has not provided any support migration path from other subscription types to CSP. Without a migration tool, this means that CSP will be limited to new installations that require little to no integration to any previously deployed resources.
A Microsoft employee, Paulo Ramos (working as a Datacenter CoE Architect, I believe), has published an excellent open source migration solution on GitHub called migAz. The migAz solution will:
The source machines remain unchanged in the original subscription. This allows you to test out a migration, with minimal impact, before you make a commitment to switch over to the ARM / CSP subscription.
This all sounds like it’s going to be a messy experience; I can tell you that, after I tested migAz out, it’s actually a pretty clean solution that allows you to customize as much or as little as you want to. I think that migAz might be the way to get virtual machines moved into CSP subscriptions.
The disks of the source virtual machines are copies using a one-time-only snapshot. If customers are still using the source virtual machines after the copy, then data will be lost during the switchover. So you have a choice:
I created a classic deployment of Azure virtual machines in the older Azure Management Portal in an Azure in Open subscription. This deployment was comprised of:
The older management portal doesn’t do resource groups, so Azure created a messy collection of resource groups to store the classic resources.
I want to move this entire classic application deployment from Azure in Open to a single tidy resource group in my new Azure in CSP subscription (ARM).
The solution is based on PowerShell so make sure that you have the latest versions of the Azure and AzureRM PowerShell modules.
You will also need to:
In my example, I extracted the migAz files to C:TempmigAz. One of the resulting files is migAz.exe. Run this file (override Windows SmartScreen if you feel safe about it, if required). Do the following:
The job will take a few minutes to run. A pair of JSON files were created for me:
The export.json file is quite an interesting read. For example, you can see how a cloud service with endpoints will be re-deployed as an Azure ARM load balancer with load balancing and NAT rules. If you want, you can modify this JSON file to change the deployment or to add extra resources. In my case, I made no changes, but I could have configured the new deployment to use a different network address so that I could have parallel connections to both the classic and ARM deployments during a pre-switch testing phase.
One of the very cool things about ARM is that you can very easily and quickly deploy a complex service with a single line of PowerShell and a JSON file. We have a JSON file (export.json) and we have installed the latest version of PowerShell …
Launch PowerShell and log into your destination Azure subscription using the Azure ARM module:
Login-AzureRmAccount
Check your available subscriptions:
Get-AzureRmSubscription
Select your desired subscription with:
Select-AzureRmSubscription -SubscriptionId “<The ID of the destination subscription>”
You will need to create a resource group to store the migrated resources. You can do this using PowerShell:
New-AzureRMResourceGroup -Name “<Name of the new resource group>” -Location “<Name of the desired Azure region>”
Now you will create a new ARM deployment from export.json:
New-AzureRMResourceGroupDeployment -Name “<Desired name of the new deployemnt>” -ResourceGroupName “<Name of the new resource group>” -TemplateFile “<Path to export.json>” -Verbose
Site back and relax; Azure will start to deploy your virtual machines and all of their dependencies … except for the virtual hard disks! This will result in a warning, as you can see below.
The next step will be to copy the virtual hard disks from the source subscription to a shiny, new, but empty storage account in the destination Azure subscription. Don’t worry; you do not need to download and upload huge files. We can use Azure’s APIs to do a copy within the Azure network; migAz includes a script to do this using the information stored in copyblobdetails.json.
Browse to the extracted location of migAz in the PowerShell window and run BlobCopy.ps1 (you will need to allow unsigned scripts to run):
.BlobCopy.ps1 -ResourcegroupName “<Name of the new resource group>” -DetailsFilePath "<Path to copyblobdetails.json>" -StartType StartBlobCopy
This script will kick off copy jobs that run in the background. You can monitor the progress of the jobs by running:
.BlobCopy.ps1 -ResourcegroupName “<Name of the new resource group>” -DetailsFilePath "<Path to copyblobdetails.json>" -StartType MonitorBlobCopy
In my case, the copy was completed faster than I could type the monitor command!
You should re-run the New-AzureRMResourceGroupDeployment cmdlet to fix up the virtual machines with the freshly imported virtual hard disks:
New-AzureRMResourceGroupDeployment -Name “<Desired name of the new deployemnt>” -ResourceGroupName “<Name of the new resource group>” -TemplateFile “<Path to export.json>” –Verbose
You can now use PowerShell and the Azure Portal to inspect and test the deployment of your virtual machines in Azure. The virtual machines are running in your ARM / CSP subscription, but no clients should be accessing them yet.
When I log into the Azure Portal, I can see that my previously messy service is now contained within a single (highlighted) resource group. An availability set and a load balancer was created instead of a cloud service.
I can verify that my endpoints have been converted into NAT rules in the load balancer.
The old service was a very classic deployment:
Once I am ready to switch over, I should either create a VPN/ExpressRoute connection and/or change my public IP addresses to start using the public IP address of the Azure load balancer.
If I am not happy about switching over, I can leave everything unchanged and stick with the classic deployment in the source Azure subscription – I can delete the ARM resources in the destination subscription without users noticing.