Moving your Azure SQL Virtual Machines to a different resource group

When you deal with SQL Server VMs on Azure, there are many operations that you didn’t have to do for on-premises systems.   One of the tasks I get asked as side questions when dealing with SQL issues is how to move SQL VMs to a different resource group.  It’s one of those things that you didn’t bother to plan and later found out that your VMs are in “group-1”, “group-2” etc.

Move resources to new resource group or subscription has basic steps on how to do the move.   But usually SQL Server is move involved. I”m sharing lessons learned.  For example, I have the following configuration for my AlwaysOn.

 

image

 

When you look at this configuration, there are a few challenges.

First of all, the AG group contains multiple resources. you can’t just move one but not the other.  You can’t just move VMs but not domain names.  if you try to move just VM, you will get errors like

Move-AzureRmResource : {"Error":{"Code":"ResourceMoveFailed","Target":null,"Message":"Resources '/subscriptions/9a4d91e7-d53a-4b70-a7c2-549a18579a9e/resourceGroups/testmove8898/providers/Microsoft.ClassicCompute/virtualMachines/testmove' could not be

moved. The tracking Id is 'fea3187d-7e67-4f69-8354-9ca5184ae9ef'","Details":[{"Code":null,"Target":"Microsoft.ClassicCompute/virtualMachines","Message":"{\"error\":{\"code\":\"NoDomainNamesToMove\",\"message\":\"Move request contains virtual machines but

not the domain names.\"}}","Details":null}]}}

At line:2 char:1

+ Move-AzureRmResource -DestinationResourceGroupName "Group-1" -Resourc ...

+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

+ CategoryInfo : CloseError: (:) [Move-AzureRmResource], ErrorResponseMessageException

+ FullyQualifiedErrorId : Conflict,Microsoft.Azure.Commands.ResourceManager.Cmdlets.Implementation.MoveAzureResourceCommand

 

Secondly, I got lots of duplicate names.  How do you deal with that?

 

Here are lessons learned from helping customers.

  1. You should always verify your subscription first.  You may have multiple subscriptions in same login and then you can’t find your resource to move.  This has led down some goose chase.
  2. Specify resource type when using Get-AzureRmResource  if you have duplicate names
  3. Move all resources (if they support the move) and their dependencies together in one move.  For example, VMs depend on domain names (or cloud service names).   You must move them together.
  4. You can move Azure classic deployment as well
  5. Not every resource supports moving resource groups. As an example, classic VNET doesn’t support moving resources.
  6. You can’t move them together if resources don’t belong to the same provider.  This is because one move request can only contain resources of only 1 provider.  For example, you can’t move storage together with VMs

 

Below is an example of moving above configuration from ag2000 to DataTier

#install powershell https://azure.microsoft.com/en-us/documentation/articles/powershell-install-configure/
#review https://azure.microsoft.com/en-us/documentation/articles/resource-group-move-resources/

#login to Azure RM account
login-azurermaccount

#get Azure Subscription associated with this account
Get-AzureRmSubscription

# To select a default subscription for your current session
Get-AzureRmSubscription –SubscriptionName “<subscription nanme>” | Select-AzureRmSubscription

# verify your default subscription
Get-AzureRmContext

#get azure resource groups
get-azurermresourcegroup | sort-object -Property ResourceGroupName |select ResourceGroupName

#new resource group
New-AzureRmResourceGroup -Name "DataTier" -Location "South Central US"

#find all resources associated with group -1
Find-AzureRmResource  -ResourceGroupNameContains ag2000 |select ResourceGroupName,Name, ResourceType, Location

 

#moving multiple resource together if there are dependencies (such as domain name that a VM depends on)
$sourcegroup="ag2000"
$destgroup="DataTier"
#$vnet=Get-AzureRmResource -ResourceName ag2000 -ResourceGroupName $sourcegroup -ResourceType Microsoft.ClassicNetwork/virtualNetworks
$domainname=Get-AzureRmResource -ResourceName agdc -ResourceGroupName $sourcegroup -ResourceType Microsoft.ClassicCompute/domainNames
#$storage =Get-AzureRmResource -ResourceName ag2000 -ResourceGroupName $sourcegroup -ResourceType Microsoft.ClassicStorage/storageAccounts
$dc=Get-AzureRmResource -ResourceName agdc -ResourceGroupName $sourcegroup -ResourceType Microsoft.ClassicCompute/virtualMachines
$vm1 = Get-AzureRmResource -ResourceName agsql1 -ResourceGroupName $sourcegroup -ResourceType Microsoft.ClassicCompute/virtualMachines
$vm2 = Get-AzureRmResource -ResourceName agsql2 -ResourceGroupName $sourcegroup -ResourceType Microsoft.ClassicCompute/virtualMachines
$vm3 = Get-AzureRmResource -ResourceName "ag-sql3"  -ResourceGroupName $sourcegroup -ResourceType Microsoft.ClassicCompute/virtualMachines

Move-AzureRmResource -DestinationResourceGroupName $destgroup -ResourceId $domainname.ResourceId,$dc.ResourceId,$vm1.ResourceId,$vm2.ResourceId,$vm3.ResourceId

 

 

#verify that resources are in the new group
Find-AzureRmResource  -ResourceGroupNameContains DataTier |select ResourceGroupName,Name, ResourceType, Location

 

 

image

 

 

Jack Li |Senior Escalation Engineer | Microsoft SQL Server

twitter| pssdiag |Sql Nexus