Migrating a Windows Azure VM to Amazon Web Services (AWS) is a little tricky and takes quite a while. But if you build a PowerShell script to repeat the behavior, it makes things much easier!

Prerequisites ^

Before we get too crazy, let's first ensure you meet all the prerequisites to make this migration happen. I'll expect you to have:

  • Azure and AWS accounts
  • An Azure storage account
  • At least one sysprepped Windows VM running in Azure
  • An AWS Simple Storage Service (S3) bucket available to store VM images
  • The AWSPowerShell module

We could transfer the virtual hard disk (VHD) for the VM we're going to migrate on premises and then back to AWS, but why? Wouldn't it be more efficient to transfer it directly from Azure to AWS? Yes! In case, we're going to be using the Azure Cloud Shell and an Azure file share. These two services will allow us to run everything we need to in Azure and communicate directly with AWS from there.

Creating the Azure file share ^

In the Cloud Shell, let's create a temporary Azure file share using an existing storage account. We'll tear this down when we're done. We'll then need to mount this file share to save the Azure VM's VHD to it eventually.

Preparing AWS ^

We'll be using AWS's VM Import/Export service to accept the VM's VHD. This service requires a role and a policy assigned to it. To build these, we'll need to create two JavaScript Object Notation (JSON) files. From within Cloud Shell, we'll use them as input into a couple of PowerShell commands.

I'll create two JSON files called servicerole.json and policy.json as shown below. Be sure to replace disk-image-file-bucket in the policy JSON with the S3 bucket name you'll be uploading the image to.

Save these to your local disk somewhere. We'll now need to upload these files to the Azure file share we created earlier. For instructions on how to do that, you can refer to the Azure documentation.

Once the JSON files are in the Azure file share you just created, you can now reference them to create the service role and assign the role policy to the service role as shown below.

Begin the download ^

We're now finally ready to do the virtual disk image transfer. For this step, we first need to figure out where the VHD attached to our Azure VM is. To do this, we can use the Get-AzureRmVm command. The Uniform Resource Identifier (URI) for the VHD is buried in a few different properties, but we can quickly pull it out with PowerShell. Be sure to change the resource group name!

Once we know the VHD URI, we can then use the Save-AzureRmVhd command to download it to our mounted Azure file share drive.

At this point, you're going to wait awhile. Depending on the size of the VHD, this can take up to 30 minutes or so.

Import into AWS ^

After saving the VHD locally, we now need to upload it to our S3 bucket. This step will definitely take awhile, regardless of whether you're using a direct connection from Azure to AWS. My 127-GB VHD took about 45 minutes to transfer over successfully. Luckily, we can use the Write-S3Object command, which will automatically perform the upload via multipart upload. This means the speed will be better, and it will be more resilient. Again, be sure to change the S3 bucket name.

Finally, we can create an AWS image. To create the Amazon Machine Image (AMI), we'll have to convert the VHD into an AMI. The PowerShell command to do this is Import-EC2Image. Below is a quick snippet on how to do this, but if you'd like more information about this command, AWS has a great writeup on it.

This will kick off the import task, which may take awhile again. We can use the Get-EC2ImportImageTask command to check on the process status periodically.

Cheking the status

Cheking the status

This process will also take awhile, so go grab lunch. But after this, the entire migration process is over! You now have a VM running in AWS that was running in Azure.

Cleanup ^

Since I'd rather not get charged for resources I won't be using after this migration, it's important to clean up. During the migration process, we created an Azure file share to store the VHD before transferring it to AWS temporarily. We don't need this anymore, so I'll now clean it up with PowerShell.

PS> Remove-AzureStorageShare -Name migrationstorage -Context $storageContext

Summary ^

Migrating VMs can be a daunting task. In this article, we covered only the basics. We were able to move a VM from Azure to AWS, but we assumed a lot. You'll have to look at lots of different bits and pieces before attempting to move production VMs like this. If you're going to be migrating lots of Azure VMs, I'd suggest taking a look at the AWS Server Migration Service. It aims to support large VM migration scenarios. It will be a better option instead of the ad-hoc approach we've taken here.

Want to write for 4sysops? We are looking for new authors.

Read 4sysops without ads by becoming a member!

  1. Franck 12 months ago


    Thank for your great blog, but I had an error when I execut tle next line

    $credential = New-Object System.Management.Automation.PSCredential ‑ArgumentList "Azure\$($storageAccount.StorageAccountName)", $secKey



  2. George Dean 7 months ago

    Does anyone know that format of "Import-EC2Image -DiskContainer $container" if you need to specify multiple volumes during import?


Leave a reply

Your email address will not be published. Required fields are marked *


© 4sysops 2006 - 2020


Please ask IT administration questions in the forums. Any other messages are welcome.


Log in with your credentials


Forgot your details?

Create Account