Moving an ARM VM to a new Vnet
I'm posting this for a college of mine:
Credited Eric Ashton
From time to time it might make sense to move a VM from one VNET to another. In the classic Azure portal this was fairly easy. We could remove the Virtual machine in the classic portal (which left the VHD behind in the storage account) and then create a new VM from “My Disks” to reattach the VHD and specify the new VNET. In the newer ARM portal this option doesn’t currently exist. We can however use some PowerShell magic to move a Virtual Machine in ARM to a new VNET.
In my example scenario I have a VM named “CentralVm” that lives in the Central US region, and I want to move it into a VNET called “vnetEast” in the East US region. Because my VM resides in a storage account in the Central region, and the VNET I want to move the VM into is in the East US region, I will first need to move the VHD for the VM from the storage account in the Central region into a storage account in the East US region.
If you are in a situation where you need to move a VM to a new VNET within the same region, you can skip down to the third script (step 5).
Before we begin we should gather some information from the Azure portal about the virtual machine we want to move, and about the VNET we want to move to.
My VM details:
VMNAME: CentralVm
Region: Central US
Resource Group: rgCentral
VM Size: Standard_DS11
The StorageAccount that holds the VHD for the VM: rgcentral8983
Name of the VHD in the rgcentral8983 storage account for this VM: CentralVM2016118102459
Full path of the VHD in the rgcentral8983 storage account: https://rgcentral8983.blob.core.windows.net/vhds/CentralVM2016118102459.vhd
Access Key for storage account source: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
The details of the VNET I want to move my VM into:
VNET Name: vnetEast
Region: East US
Resource Group: rgEast
Subnet in vnetEast that I intend the VM to be in after the move: AppSubnet
A Storage account in the East US region where I will need to move the VHD for my VM into: rgeast9618
Access Key for storage account destination: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Now that we have the required information we can use the following scripts to move my VM named "CentralVm" into the new VNET vnetEast.
- Since I will be detaching and reattaching the VHD for this VM I need to shut down CentralVm.
- Next I will be delete the VM in the portal. This will remove the VM from the portal, however the VHD for the VM will still reside in the rgcentral8983 storage account.
At this point, if you do NOT need to move your VM to a different region you can skip down to step 5 (The VM/VHD reattach script)
- Now that CentralVm has been shut down and deleted from the azure portal, I am ready to move the detached VHD from the rgcentral8983 storage account (Central region) to the rgeast9618 storage account in the (East US region)
# MOVE VHD FROM ONE STORAGE ACCOUNT TO ANOTHER #
### Source VHD - authenticated container ###
<code>
$srcUri = "https://rgcentral8983.blob.core.windows.net/vhds/CentralVM2016118102459.vhd"
### Source Storage Account (Central) ###
$srcStorageAccount = "rgcentral8983"
$srcStorageKey = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX”
### Target Storage Account (East) ###
$destStorageAccount = "rgeast9618"
$destStorageKey = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX”
### Create the source storage accountcontext ###
$srcContext = New-AzureStorageContext –StorageAccountName $srcStorageAccount -StorageAccountKey $srcStorageKey
### Create the destination storage account context ###
$destContext = New-AzureStorageContext –StorageAccountName $destStorageAccount -StorageAccountKey $destStorageKey
### Destination Container Name ###
$containerName = "vhds"
### Start the asynchronous copy - specify the source authentication with -SrcContext ###
$blob1 = Start-AzureStorageBlobCopy -srcUri $srcUri `
-SrcContext $srcContext `
-DestContainer $containerName `
-DestBlob "CentralVM2016118102459.vhd" `
-DestContext $destContext
- This should run without an error. We can then watch the copy progress with the following script:
### Retrieve the current status of the copy operation ###
$status = $blob1 | Get-AzureStorageBlobCopyState
### Print out status ###
$status
### Loop until complete ###
While($status.Status -eq "Pending"){
$status = $blob1 | Get-AzureStorageBlobCopyState
Start-Sleep 10
### Print out status ###
$status
}
- Once we see the message that the copy has been completed, we are ready to create a new VM in the East US region using the VHD that we just copied over.
## Create new VM from detached VHD ##
#This is the ResourceGroup that holds the VNET we are trying to load the VM into
$RG='rgEast'
#Name of the VNET we are trying to load the VM into
$NetworkName='vnetEast'
#Subnet in the vnet we are trying to move the VM into
$SubnetName='AppSubnet'
#New Public IP name
$PIPName='MovedVMpip'
#New Nic name that will get created in the VNET we are moving the VM to
$Nic1Name='MovedVMnic'
#New Virtual Machine Name
$VMName='CentralVm'
#The storage account that holds the VHD we are trying to make a new VM from.
$storageaccount='rgeast9618'
#Name of the VHD that resided in the $storageaccount
$VHDName='CentralVM2016118102459'
#New Public IP DNS name
$PIPDNSName='movedvmdns'
#VMSize
$VMSize='Standard_DS11'
#The resource group that $storageaccount resides in
$StorageRg='rgEast'
#The location where $storageaccount resides
$Location='eastus'
$network=Get-AzureRmVirtualNetwork -Name $NetworkName -ResourceGroupName $RG
$subnet=Get-AzureRmVirtualNetworkSubnetConfig -Name $SubnetName -VirtualNetwork $network
$Stor=Get-AzureRmStorageAccount -ResourceGroupName $StorageRg -Name $storageaccount
$pip=New-AzureRmPublicIpAddress -Name $PIPName -ResourceGroupName $Rg -Location $Location -DomainNameLabel $PIPDNSName -AllocationMethod Dynamic
$nic1=New-AzureRmNetworkInterface -Name $Nic1Name -ResourceGroupName $Rg -Location $Location -SubnetId $subnet.Id -EnableIPForwarding -PublicIpAddressId $pip.Id
$VM=New-AzureRmVMConfig -VMName $VMName -VMSize $VMSize
$VM=Add-AzureRmVMNetworkInterface -Id $nic1.id -VM $VM -Primary
$OSDiskUri=$Stor.PrimaryEndpoints.Blob.ToString() + 'vhds/' +$VHDName +'.vhd'
$VM=Set-AzureRmVMOSDisk -Name $VHDName -VhdUri $OSDiskUri -Caching ReadWrite -CreateOption attach -Windows -VM $VM
New-AzureRmVM -ResourceGroupName $RG -Location $location -VM $VM
#Stop Script
==========================================================
Done! Now when we look in the portal we will find that our VM has been recreated and resides in the target region/vnet.
Comments
- Anonymous
August 12, 2016
excellent. helped a lot.