Monday, November 9, 2020

Azure Site Recovery (ASR) with Proximity Placement Groups (PPG) to another region

What is Proximity Placement Groups and why we need them?

Proximity Placement Groups is an Azure Virtual Machine logical grouping capability that you can use to decrease the inter-VM network latency associated with your applications. When the VMs are deployed within the same proximity placement group, they are physically located as close as possible to each other. Proximity placement groups are particularly useful to address the requirements of latency-sensitive workloads.

 

The VM is in the East US region. The recovery region selected for disaster recovery is the West US 2 region. The recovery services vault,resource group of the vault both are in the recovery region( West US 2).

 NOTE: You need to create PPG in recovery region or else it will fail. 

 

# --------------------   Azure to Azure   ----------------------------------------
#1. Sign in to your account and set your subscription.

Connect-AzAccount

#2. Get the details of the virtual machine you’re planning to replicate as mentioned here.
# Get details of the virtual machine

$VM = Get-AzVM -ResourceGroupName "PPG-EU" -Name "WindowsVM"        
Write-Output $VM

#3. Create your recovery services vault and set the vault context. #Create a resource group for the recovery services vault in the recovery Azure region

New-AzResourceGroup -Name "PPG-WU2" -Location "West US 2"

#Create a new Recovery services vault in the recovery region
$vault = New-AzRecoveryServicesVault -Name "WU2RecoveryVault" -ResourceGroupName "PPG-WU2" -Location "West US 2"
Write-Output $vault

#Setting the vault context.
Set-AzRecoveryServicesAsrVaultContext -Vault $vault

#4 Prepare the vault to start replication virtual machine. This involves creating a service fabric object for both primary and recovery regions.

#Create Primary ASR fabric
$TempASRJob = New-AzRecoveryServicesAsrFabric -Azure -Location 'East US'  -Name "A2Ademo-EastUS"
# Track Job status to check for completion
while (($TempASRJob.State -eq "InProgress") -or ($TempASRJob.State -eq "NotStarted")){
        #If the job hasn't completed, sleep for 10 seconds before checking the job status again
        sleep 10;
        $TempASRJob = Get-AzRecoveryServicesAsrJob -Job $TempASRJob
}
#Check if the Job completed successfully. The updated job state of a successfully completed job should be "Succeeded"
Write-Output $TempASRJob.State
$PrimaryFabric = Get-AzRecoveryServicesAsrFabric -Name "A2Ademo-EastUS"

#Create Recovery ASR fabric
$TempASRJob = New-AzRecoveryServicesAsrFabric -Azure -Location 'West US 2'  -Name "A2Ademo-WestUS"
# Track Job status to check for completion
while (($TempASRJob.State -eq "InProgress") -or ($TempASRJob.State -eq "NotStarted")){
        sleep 10;
        $TempASRJob = Get-AzRecoveryServicesAsrJob -Job $TempASRJob
}
#Check if the Job completed successfully. The updated job state of a successfully completed job should be "Succeeded"
Write-Output $TempASRJob.State
$RecoveryFabric = Get-AzRecoveryServicesAsrFabric -Name "A2Ademo-WestUS"


#5.Create a Site Recovery protection container, for both the primary and recovery fabrics
#Create a Protection container in the primary Azure region (within the Primary fabric)
$TempASRJob = New-AzRecoveryServicesAsrProtectionContainer -InputObject $PrimaryFabric -Name "A2AEastUSProtectionContainer"
#Track Job status to check for completion
while (($TempASRJob.State -eq "InProgress") -or ($TempASRJob.State -eq "NotStarted")){
        sleep 10;
        $TempASRJob = Get-AzRecoveryServicesAsrJob -Job $TempASRJob
}
Write-Output $TempASRJob.State
$PrimaryProtContainer = Get-AzRecoveryServicesAsrProtectionContainer -Fabric $PrimaryFabric -Name "A2AEastUSProtectionContainer"


#Create a Protection container in the recovery Azure region (within the Recovery fabric)
$TempASRJob = New-AzRecoveryServicesAsrProtectionContainer -InputObject $RecoveryFabric -Name "A2AWestUSProtectionContainer"
#Track Job status to check for completion
while (($TempASRJob.State -eq "InProgress") -or ($TempASRJob.State -eq "NotStarted")){
        sleep 10;
        $TempASRJob = Get-AzRecoveryServicesAsrJob -Job $TempASRJob
}
#Check if the Job completed successfully. The updated job state of a successfully completed job should be "Succeeded"
Write-Output $TempASRJob.State
$RecoveryProtContainer = Get-AzRecoveryServicesAsrProtectionContainer -Fabric $RecoveryFabric -Name "A2AWestUSProtectionContainer"


#6 Create a replication policy

#Create replication policy
$TempASRJob = New-AzRecoveryServicesAsrPolicy -AzureToAzure -Name "A2APolicy" -RecoveryPointRetentionInHours 24 -ApplicationConsistentSnapshotFrequencyInHours 4
#Track Job status to check for completion
while (($TempASRJob.State -eq "InProgress") -or ($TempASRJob.State -eq "NotStarted")){
        sleep 10;
        $TempASRJob = Get-AzRecoveryServicesAsrJob -Job $TempASRJob
}
#Check if the Job completed successfully. The updated job state of a successfully completed job should be "Succeeded"
Write-Output $TempASRJob.State
$ReplicationPolicy = Get-AzRecoveryServicesAsrPolicy -Name "A2APolicy"

#Create Protection container mapping between the Primary and Recovery Protection Containers with the Replication policy
$TempASRJob = New-AzRecoveryServicesAsrProtectionContainerMapping -Name "A2APrimaryToRecovery" -Policy $ReplicationPolicy -PrimaryProtectionContainer $PrimaryProtContainer -RecoveryProtectionContainer $RecoveryProtContainer
#Track Job status to check for completion
while (($TempASRJob.State -eq "InProgress") -or ($TempASRJob.State -eq "NotStarted")){
        sleep 10;
        $TempASRJob = Get-AzRecoveryServicesAsrJob -Job $TempASRJob
}
#Check if the Job completed successfully. The updated job state of a successfully completed job should be "Succeeded"
Write-Output $TempASRJob.State
$EusToWusPCMapping = Get-AzRecoveryServicesAsrProtectionContainerMapping -ProtectionContainer $PrimaryProtContainer -Name "A2APrimaryToRecovery"


#7.Create a protection container mapping between primary and recovery protection container using these steps and a protection container mapping for failback as mentioned here.
#Create Protection container mapping (for fail back) between the Recovery and Primary Protection Containers with the Replication policy
$TempASRJob = New-AzRecoveryServicesAsrProtectionContainerMapping -Name "A2ARecoveryToPrimary" -Policy $ReplicationPolicy -PrimaryProtectionContainer $RecoveryProtContainer -RecoveryProtectionContainer $PrimaryProtContainer
#Track Job status to check for completion
while (($TempASRJob.State -eq "InProgress") -or ($TempASRJob.State -eq "NotStarted")){
        sleep 10;
        $TempASRJob = Get-AzRecoveryServicesAsrJob -Job $TempASRJob
}
#Check if the Job completed successfully. The updated job state of a successfully completed job should be "Succeeded"
Write-Output $TempASRJob.State
$WusToEusPCMapping = Get-AzRecoveryServicesAsrProtectionContainerMapping -ProtectionContainer $RecoveryProtContainer -Name "A2ARecoveryToPrimary"


#Create Protection container mapping (for fail back) between the Recovery and Primary Protection Containers with the Replication policy
$TempASRJob = New-AzRecoveryServicesAsrProtectionContainerMapping -Name "A2ARecoveryToPrimary" -Policy $ReplicationPolicy -PrimaryProtectionContainer $RecoveryProtContainer -RecoveryProtectionContainer $PrimaryProtContainer
#Track Job status to check for completion
while (($TempASRJob.State -eq "InProgress") -or ($TempASRJob.State -eq "NotStarted")){
        sleep 10;
        $TempASRJob = Get-AzRecoveryServicesAsrJob -Job $TempASRJob
}
#Check if the Job completed successfully. The updated job state of a successfully completed job should be "Succeeded"
Write-Output $TempASRJob.State
$WusToEusPCMapping = Get-AzRecoveryServicesAsrProtectionContainerMapping -ProtectionContainer $RecoveryProtContainer -Name "A2ARecoveryToPrimary"


#8. Create cache storage account by following these steps.

#Create Cache storage account for replication logs in the primary region
$EastUSCacheStorageAccount = New-AzStorageAccount -Name "az12az1cachestorage" -ResourceGroupName "PPG-EU" -Location 'East US' -SkuName Standard_LRS -Kind Storage
#$EastUSCacheStorageAccount = Set-AzStorageAccount -ResourceGroupName "PPG-EU" -AccountName "az12az1cachestorage" -SkuName Standard_LRS

#Create Target storage account in the recovery region. In this case a Standard Storage account
$WestUSTargetStorageAccount = New-AzStorageAccount -Name "az12az1targetstorage" -ResourceGroupName "PPG-WU2" -Location 'West US 2' -SkuName Standard_LRS -Kind Storage


#9 Create the required network mappings as mentioned here.
#Create a Recovery Network in the recovery region
$WestUSRecoveryVnet = New-AzVirtualNetwork -Name "a2arecoveryvnet" -ResourceGroupName "PPG-WU2" -Location 'West US 2' -AddressPrefix "10.2.0.0/16"
Add-AzVirtualNetworkSubnetConfig -Name "default" -VirtualNetwork $WestUSRecoveryVnet -AddressPrefix "10.2.0.0/20" | Set-AzVirtualNetwork
$WestUSRecoveryNetwork = $WestUSRecoveryVnet.Id

#Retrieve the virtual network that the virtual machine is connected to
#Get first network interface card(nic) of the virtual machine
$SplitNicArmId = $VM.NetworkProfile.NetworkInterfaces[0].Id.split("/")
#Extract resource group name from the ResourceId of the nic
$NICRG = $SplitNicArmId[4]
#Extract resource name from the ResourceId of the nic
$NICname = $SplitNicArmId[-1]
#Get network interface details using the extracted resource group name and resource name
$NIC = Get-AzNetworkInterface -ResourceGroupName $NICRG -Name $NICname
#Get the subnet ID of the subnet that the nic is connected to
$PrimarySubnet = $NIC.IpConfigurations[0].Subnet
# Extract the resource ID of the Azure virtual network the nic is connected to from the subnet ID
$EastUSPrimaryNetwork = (Split-Path(Split-Path($PrimarySubnet.Id))).Replace("\","/")


#Create an ASR network mapping between the primary Azure virtual network and the recovery Azure virtual network
$TempASRJob = New-AzRecoveryServicesAsrNetworkMapping -AzureToAzure -Name "A2AEusToWusNWMapping" -PrimaryFabric $PrimaryFabric -PrimaryAzureNetworkId $EastUSPrimaryNetwork -RecoveryFabric $RecoveryFabric -RecoveryAzureNetworkId $WestUSRecoveryNetwork
#Track Job status to check for completion
while (($TempASRJob.State -eq "InProgress") -or ($TempASRJob.State -eq "NotStarted")){
    sleep 10;
    $TempASRJob = Get-AzRecoveryServicesAsrJob -Job $TempASRJob
  }
#Check if the Job completed successfully. The updated job state of a successfully completed job should be "Succeeded"
Write-Output $TempASRJob.State

 

#Create an ASR network mapping for fail back between the recovery Azure virtual network and the primary Azure virtual network
$TempASRJob = New-AzRecoveryServicesAsrNetworkMapping -AzureToAzure -Name "A2AWusToEusNWMapping" -PrimaryFabric $RecoveryFabric -PrimaryAzureNetworkId $WestUSRecoveryNetwork -RecoveryFabric $PrimaryFabric -RecoveryAzureNetworkId $EastUSPrimaryNetwork
#Track Job status to check for completion
while (($TempASRJob.State -eq "InProgress") -or ($TempASRJob.State -eq "NotStarted")){
        sleep 10;
        $TempASRJob = Get-AzRecoveryServicesAsrJob -Job $TempASRJob
}
#Check if the Job completed successfully. The updated job state of a successfully completed job should be "Succeeded"
Write-Output $TempASRJob.State

#10. To replicate Azure virtual machine with managed disks, use the below PowerShell cmdlet
#To replicate Azure virtual machine with managed disks, use the below PowerShell cmdlet -

#Get the resource group that the virtual machine must be created in when failed over.
$RecoveryRG = Get-AzResourceGroup -Name "PPG-WU2" -Location "West US 2"

#Replication OS Disk and Data Disks

$OSdiskId = $vm.StorageProfile.OsDisk.ManagedDisk.Id
$OSDisk = get-azdisk -ResourceGroupName $vm.ResourceGroupName -DiskName $OSdiskId.split('/')[-1]
$RecoveryOSDiskAccountType = $osdisk.sku.name
$RecoveryReplicaDiskAccountType = $osdisk.sku.name


$OSDiskReplicationConfig = New-AzRecoveryServicesAsrAzureToAzureDiskReplicationConfig -ManagedDisk -LogStorageAccountId $EastUSCacheStorageAccount.Id `
         -DiskId $OSdiskId -RecoveryResourceGroupId  $RecoveryRG.ResourceId -RecoveryReplicaDiskAccountType  $RecoveryReplicaDiskAccountType `
         -RecoveryTargetDiskAccountType $RecoveryOSDiskAccountType


# Data disk
$datadiskId1 = $vm.StorageProfile.DataDisks[0].ManagedDisk.Id
$Datadisk1 = get-azdisk -ResourceGroupName $vm.ResourceGroupName -DiskName $datadiskId1.split('/')[-1]
$RecoveryReplicaDiskAccountType = $datadisk1.sku.name
$RecoveryTargetDiskAccountType = $datadisk1.sku.name

$DataDisk1ReplicationConfig  = New-AzRecoveryServicesAsrAzureToAzureDiskReplicationConfig -ManagedDisk -LogStorageAccountId $EastUSCacheStorageAccount.Id `
         -DiskId $datadiskId1 -RecoveryResourceGroupId $RecoveryRG.ResourceId -RecoveryReplicaDiskAccountType $RecoveryReplicaDiskAccountType `
         -RecoveryTargetDiskAccountType $RecoveryTargetDiskAccountType


# Data disk 2
$datadiskId2 = $vm.StorageProfile.DataDisks[1].ManagedDisk.Id
$Datadisk2 = get-azdisk -ResourceGroupName $vm.ResourceGroupName -DiskName $datadiskId2.split('/')[-1]
$RecoveryReplicaDiskAccountType = $datadisk2.sku.name
$RecoveryTargetDiskAccountType = $datadisk2.sku.name

$DataDisk2ReplicationConfig  = New-AzRecoveryServicesAsrAzureToAzureDiskReplicationConfig -ManagedDisk -LogStorageAccountId $EastUSCacheStorageAccount.Id `
         -DiskId $datadiskId2 -RecoveryResourceGroupId $RecoveryRG.ResourceId -RecoveryReplicaDiskAccountType $RecoveryReplicaDiskAccountType `
         -RecoveryTargetDiskAccountType $RecoveryTargetDiskAccountType


#Create a list of disk replication configuration objects for the disks of the virtual machine that are to be replicated.
$diskconfigs = @()
$diskconfigs += $OSDiskReplicationConfig, $DataDisk1ReplicationConfig, $DataDisk2ReplicationConfig


#Get the PPG ID from the target region
$targetPpg =Get-AzProximityPlacementGroup -Name Poc-ppg-eu -ResourceGroupName PPG-WU2
$targetPpg.id

#Start replication by creating replication protected item. Using a GUID for the name of the replication protected item to ensure uniqueness of name.
$TempASRJob = New-AzRecoveryServicesAsrReplicationProtectedItem -AzureToAzure -AzureVmId $VM.Id -Name (New-Guid).Guid -ProtectionContainerMapping $EusToWusPCMapping -AzureToAzureDiskReplicationConfiguration $diskconfigs -RecoveryResourceGroupId $RecoveryRG.ResourceId -RecoveryProximityPlacementGroupId $targetPpg.Id

 

Tuesday, October 20, 2020

Move Azure Resources from one Azure region to another by using Azure Resource Mover (ASM) [Public Preview]

 

 

Azure Resource Mover is a new service in Azure that lets you move resources across regions.

• Move resources from one resource group to another resource group
• Move resource from one Azure subscription to another

 

Azure resource mover supports only the following types of resources

• Azure VMs and associated disks
• NICs
• Availability sets
• Azure virtual networks
• Public IP addresses
• Network security groups (NSGs)
• Internal and public load balancers
• Azure SQL databases and elastic pools

Azure Resource Mover requires either Owner or Contributor and User Access Administrator permissions on subscription level for the first time resources are moved for a source / target region pair.

 

Moving a VM from East US to West US

 

1)      Log in to Azure Portal as Global Administrator

2)      Click on Resource groups  and click on the Source Resource group

3)      Select resources need to move to another region (or) you can search for Azure Resource Mover in the Azure portal and using the Resource Mover interface you specify the subscription and the source as well the target region.

4)      Click on move then click on move to another region

 

 

 

Note: If you are moving an VM, do not select VM disks separately. VM disks are moved as part of the selected VM. Otherwise, it will give an error during the validation.

5)      Select West US as the destination region. Then click on Next to proceed.

 

 

6)      In Move resources window, verify there are no errors. Then click Next to proceed

 

 

 

7)      In the Review + Add page, accept the changes and click on Proceed.

 

 

8)      In Azure Resource Mover page. Click on validate dependencies before starting the prepare step.

 

 

9)      When dependencies exist add them to the resource list with add dependencies.

 

 

 

 

10)   Once dependencies are added, select the source resource group you want to move and click on prepare but only for the resource group.

Note: It is a requirement that the resource group need to be moved first before you start with the other resources.

 


 

        11)   The next steps are prepare, initiate move and commit move.

 


 

12)   Once resource group status is changed to Initiate move‘ pending, select it and click on Initiate move

 


 

13)   On the next page, verify the selection of resources and click on Initiate Move

 


 

14)   After a few minutes the status of the resource group will change to ‘Commit move‘ pending. Then select it and click on Commit Move.

 


 

15)   On the next page, verify the selection of resources and click on Commit.

 


 

16)   Once the resource group status changed to ‘Delete source‘ pending. This means the move is completed for the resource group.

 


 

17)   Now follow the same steps (Prepare, Initiate move & Commit move) and move other resources.

 


 

18)   Prepare step will take time to complete when moving a VM and in the background the Azure Site Recovery agent gets installed on the VM and the replication process is set upped.

Note: Azure Resource Mover uses an Azure Site Recovery vault in the backend for moving VMs across regions.

 


 


 


 

19)   Once the other resources status is changed to Initiate move‘ pending, select it and click on Initiate move. During the initiate move step, the source VM gets deallocated and the target VM will get started.

 


 

20)   Once the move is completed, we can see all the resources under the new resource group.

 


 

21)   After a few minutes the status of the resources will change to ‘Commit move‘ pending. Then select it and click on Commit Move.

 


 

22)   All resources have now the status delete source pending which indicates a successful move.

 


 

23)   The VM runs in West US and the source VM in East US is deallocated.

 


24)   Logged in to the VM in the new resource group. As expected, it is working.

 


25)   Before removing the resources from Azure Resource Mover, you should delete the source resources first.

 

 

URLs:

·         https://docs.microsoft.com/en-us/azure/azure-resource-manager/management/move-region

·         https://techcommunity.microsoft.com/t5/azure-governance-and-management/introducing-azure-resource-mover-a-seamless-way-to-move-between/ba-p/1703848

·         https://docs.microsoft.com/en-us/azure/azure-resource-manager/management/move-limitations/virtual-machines-move-limitations

·         https://docs.microsoft.com/en-us/azure/azure-resource-manager/management/move-resource-group-and-subscription