Skip to content

Commit a02eba4

Browse files
authored
ASR support for Azure zone to zone replication (#11785)
* Recovery plan: zone to zone changes * updated change log * adding session record file
1 parent 497b302 commit a02eba4

File tree

10 files changed

+49736
-4
lines changed

10 files changed

+49736
-4
lines changed

src/RecoveryServices/RecoveryServices.SiteRecovery.Test/ScenarioTests/A2A/A2ATestsHelper.ps1

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,21 @@ function getPrimaryLocation
3939
return "westus"
4040
}
4141

42+
function getPrimaryZoneLocation
43+
{
44+
return "southeastasia"
45+
}
46+
47+
function getPrimaryZone
48+
{
49+
return "1"
50+
}
51+
52+
function getRecoveryZone
53+
{
54+
return "2"
55+
}
56+
4257
function getRecoveryLocation{
4358
return getVaultLocation
4459
}
@@ -83,6 +98,9 @@ function getPrimaryContainerMapping{
8398
return "A2APCM"+ $seed;
8499
}
85100

101+
function getRecoveryPlanName{
102+
return "A2ARP"+ $seed;
103+
}
86104

87105
function getRecoveryContainerMapping{
88106
return "A2ARCM"+ $seed;
@@ -172,6 +190,23 @@ function createAzureVmInProximityPlacementgroup{
172190
return $vm.Id
173191
}
174192

193+
function createAzureVmInAvailabilityZone{
194+
param([string]$primaryLocation)
195+
196+
$VMLocalAdminUser = "adminUser"
197+
$PasswordString = $(Get-RandomSuffix 12)
198+
$Password=$PasswordString| ConvertTo-SecureString -Force -AsPlainText
199+
$VMLocalAdminSecurePassword = $Password
200+
$VMLocation = getPrimaryZoneLocation
201+
$VMZone = getPrimaryZone
202+
$VMName = getAzureVmName
203+
$domain = "domain"+ $seed
204+
$password=$VMLocalAdminSecurePassword|ConvertTo-SecureString -AsPlainText -Force
205+
$Credential = New-Object System.Management.Automation.PSCredential ($VMLocalAdminUser, $password);
206+
$vm = New-AzVM -Name $VMName -Credential $Credential -location $VMLocation -Image RHEL -DomainNameLabel $domain -Zone $VMZone
207+
return $vm.Id
208+
}
209+
175210
function createRecoveryNetworkId{
176211
param([string] $location , [string] $resourceGroup)
177212

@@ -187,6 +222,21 @@ function createRecoveryNetworkId{
187222
return $virtualNetwork.Id
188223
}
189224

225+
function createRecoveryNetworkIdForZone{
226+
param([string] $location , [string] $resourceGroup)
227+
228+
$NetworkName = getRecoveryNetworkName
229+
$NetworkLocation = getPrimaryZoneLocation
230+
$ResourceGroupName = getRecoveryResourceGroupName
231+
$frontendSubnet = New-AzVirtualNetworkSubnetConfig -Name frontendSubnet -AddressPrefix "10.0.1.0/24"
232+
$virtualNetwork = New-AzVirtualNetwork `
233+
-ResourceGroupName $ResourceGroupName `
234+
-Location $NetworkLocation `
235+
-Name $NetworkName `
236+
-AddressPrefix 10.0.0.0/16 -Subnet $frontendSubnet
237+
return $virtualNetwork.Id
238+
}
239+
190240
function createCacheStorageAccount{
191241
param([string] $location , [string] $resourceGroup)
192242

@@ -201,6 +251,21 @@ function createCacheStorageAccount{
201251
return $storageAccount.Id
202252
}
203253

254+
function createCacheStorageAccountForZone{
255+
param([string] $location , [string] $resourceGroup)
256+
257+
$StorageAccountName = getCacheStorageAccountName
258+
$cacheLocation = getPrimaryZoneLocation
259+
$storageRes = getAzureVmName
260+
$storageAccount = New-AzStorageAccount `
261+
-ResourceGroupName $storageRes `
262+
-Location $cacheLocation `
263+
-Name $StorageAccountName `
264+
-Type 'Standard_LRS'
265+
return $storageAccount.Id
266+
}
267+
268+
204269

205270
function createRecoveryCacheStorageAccount{
206271
param([string] $location , [string] $resourceGroup)

src/RecoveryServices/RecoveryServices.SiteRecovery.Test/ScenarioTests/A2A/AsrA2ATests.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,5 +96,19 @@ public void A2AReplicateProximityPlacementGroupVm()
9696
{
9797
this.RunPowerShellTest(_logger, Constants.NewModel, "Test-ReplicateProximityPlacementGroupVm");
9898
}
99+
100+
[Fact]
101+
[Trait(Category.AcceptanceType, Category.CheckIn)]
102+
public void A2AZoneToZoneRecoveryPlanReplication()
103+
{
104+
this.RunPowerShellTest(_logger, Constants.NewModel, "Test-ZoneToZoneRecoveryPlanReplication");
105+
}
106+
107+
[Fact]
108+
[Trait(Category.AcceptanceType, Category.CheckIn)]
109+
public void A2ARecoveryPlanReplication()
110+
{
111+
this.RunPowerShellTest(_logger, Constants.NewModel, "Test-RecoveryPlanReplication");
112+
}
99113
}
100114
}

src/RecoveryServices/RecoveryServices.SiteRecovery.Test/ScenarioTests/A2A/AsrA2ATests.ps1

Lines changed: 248 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -547,4 +547,251 @@ function Test-ReplicateProximityPlacementGroupVm{
547547

548548
$pe = Get-AzRecoveryServicesAsrReplicationProtectedItem -ProtectionContainer $rc -Name $vmName
549549
Assert-NotNull($pe.providerSpecificDetails.RecoveryProximityPlacementGroupId)
550-
}
550+
}
551+
552+
<#
553+
.SYNOPSIS
554+
Test ZoneToZoneRecoveryPlanReplication new parametersets
555+
#>
556+
557+
function Test-ZoneToZoneRecoveryPlanReplication{
558+
param([string] $seed ='347')
559+
$primaryPolicyName = getPrimaryPolicy
560+
$recoveryPolicyName = getRecoveryPolicy
561+
562+
$primaryContainerMappingName = getPrimaryContainerMapping
563+
$recoveryContainerMappingName = getRecoveryContainerMapping
564+
565+
$primaryContainerName = getPrimaryContainer
566+
$recoveryContainerName = getRecoveryContainer
567+
$vaultRgLocation = getPrimaryZoneLocation
568+
$vaultName = getVaultName
569+
$vaultLocation = getPrimaryZoneLocation
570+
$vaultRg = getVaultRg
571+
$primaryLocation = getPrimaryZoneLocation
572+
$recoveryLocation = getPrimaryZoneLocation
573+
$primaryFabricName = getPrimaryFabric
574+
$RecoveryReplicaDiskAccountType = "Premium_LRS"
575+
$RecoveryTargetDiskAccountType = "Premium_LRS"
576+
$policyName = getPrimaryPolicy
577+
$mappingName = getPrimaryContainerMapping
578+
$recZone = getRecoveryZone
579+
$priZone = getPrimaryZone
580+
$RecoveryPlanName = getRecoveryPlanName
581+
582+
#create recovery side resources
583+
$recRgName = getRecoveryResourceGroupName
584+
New-AzResourceGroup -name $recRgName -location $recoveryLocation -force
585+
[Microsoft.Rest.ClientRuntime.Azure.TestFramework.TestUtilities]::Wait(20 * 1000)
586+
$RecoveryAzureNetworkId = createRecoveryNetworkIdForZone
587+
$index =$RecoveryAzureNetworkId.IndexOf("/providers/")
588+
$recRg =$RecoveryAzureNetworkId.Substring(0,$index)
589+
590+
#create primary
591+
$vmName = getAzureVmName
592+
New-AzResourceGroup -name $vmName -location $primaryLocation -force
593+
[Microsoft.Rest.ClientRuntime.Azure.TestFramework.TestUtilities]::Wait(20 * 1000)
594+
$logStg = createCacheStorageAccountForZone
595+
596+
$v2VmId = createAzureVmInAvailabilityZone
597+
$vm = get-azVm -ResourceGroupName $vmName -Name $vmName
598+
$vhdid =$vm.StorageProfile.OSDisk.ManagedDisk.Id
599+
$index =$vm.Id.IndexOf("/providers/")
600+
$Rg =$vm.Id.Substring(0,$index)
601+
$PrimaryAzureNetworkId = $Rg + "/providers/Microsoft.Network/virtualNetworks/" + $vmName
602+
603+
# vault Creation
604+
New-AzResourceGroup -name $vaultRg -location $vaultRgLocation -force
605+
[Microsoft.Rest.ClientRuntime.Azure.TestFramework.TestUtilities]::Wait(20 * 1000)
606+
New-AzRecoveryServicesVault -ResourceGroupName $vaultRg -Name $vaultName -Location $vaultLocation
607+
[Microsoft.Rest.ClientRuntime.Azure.TestFramework.TestUtilities]::Wait(20 * 1000)
608+
$Vault = Get-AzRecoveryServicesVault -ResourceGroupName $vaultRg -Name $vaultName
609+
Set-ASRVaultContext -Vault $Vault
610+
611+
# fabric Creation
612+
$fabJob= New-AzRecoveryServicesAsrFabric -Azure -Name $primaryFabricName -Location $primaryLocation
613+
WaitForJobCompletion -JobId $fabJob.Name
614+
$fab = Get-AzRecoveryServicesAsrFabric -Name $primaryFabricName
615+
Assert-true { $fab.name -eq $primaryFabricName }
616+
Assert-AreEqual $fab.FabricSpecificDetails.Location $primaryLocation
617+
618+
$pf = get-asrFabric -Name $primaryFabricName
619+
620+
#Container creation
621+
$job = New-AzRecoveryServicesAsrProtectionContainer -Name $primaryContainerName -Fabric $pf
622+
WaitForJobCompletion -JobId $Job.Name
623+
$pc = Get-asrProtectionContainer -name $primaryContainerName -Fabric $pf
624+
Assert-NotNull($pc)
625+
$job = New-AzRecoveryServicesAsrProtectionContainer -Name $recoveryContainerName -Fabric $pf
626+
WaitForJobCompletion -JobId $Job.Name
627+
$rc = Get-asrProtectionContainer -name $recoveryContainerName -Fabric $pf
628+
Assert-NotNull($rc)
629+
630+
#create policy and mapping
631+
$job = New-AzRecoveryServicesAsrPolicy -Name $policyName -RecoveryPointRetentionInHours 12 -AzureToAzure
632+
WaitForJobCompletion -JobId $job.Name
633+
$policy = Get-AzRecoveryServicesAsrPolicy -Name $policyName
634+
$job = New-AzRecoveryServicesAsrProtectionContainerMapping -Name $mappingName -Policy $policy -PrimaryProtectionContainer $pc -RecoveryProtectionContainer $rc
635+
WaitForJobCompletion -JobId $job.Name
636+
$mapping = Get-AzRecoveryServicesAsrProtectionContainerMapping -Name $mappingName -ProtectionContainer $pc
637+
638+
#enable Replication
639+
$v = New-AzRecoveryServicesAsrAzureToAzureDiskReplicationConfig -managed -LogStorageAccountId $logStg `
640+
-DiskId $vhdid -RecoveryResourceGroupId $recRg -RecoveryReplicaDiskAccountType $RecoveryReplicaDiskAccountType `
641+
-RecoveryTargetDiskAccountType $RecoveryTargetDiskAccountType
642+
$enableDRjob = New-AzRecoveryServicesAsrReplicationProtectedItem -AzureToAzure -AzureVmId $vm.Id -Name $vmName -ProtectionContainerMapping $mapping -RecoveryResourceGroupId $recRg -AzureToAzureDiskReplicationConfiguration $v -RecoveryAvailabilityZone $recZone -RecoveryAzureNetworkId $RecoveryAzureNetworkId -RecoveryAzureSubnetName "frontendSubnet"
643+
WaitForJobCompletion -JobId $enableDRjob.Name
644+
WaitForIRCompletion -affectedObjectId $enableDRjob.TargetObjectId
645+
646+
$pe = Get-AzRecoveryServicesAsrReplicationProtectedItem -ProtectionContainer $pc -Name $vmName
647+
Assert-NotNull($pe)
648+
649+
#Create Recovery Plan
650+
$createRecoveryJob = New-AzRecoveryServicesAsrRecoveryPlan -AzureZoneToZone -Name $RecoveryPlanName -PrimaryFabric $pf -ReplicationProtectedItem $pe -RecoveryZone $recZone -PrimaryZone $priZone
651+
WaitForJobCompletion -JobId $createRecoveryJob.Name
652+
653+
#Get Recovery Plan
654+
$RecoveryPlan = Get-AzRecoveryServicesAsrRecoveryPlan -Name $RecoveryPlanName
655+
Assert-NotNull($RecoveryPlan)
656+
657+
#Failover
658+
$failoverjob = Start-AzRecoveryServicesAsrUnPlannedFailoverJob -RecoveryPlan $RecoveryPlan -Direction PrimaryToRecovery -PerformSourceSideAction
659+
WaitForJobCompletion -JobId $failoverjob.Name
660+
#Get recovery vm and verify
661+
$recvm = get-azVm -ResourceGroupName $recRgName -Name $vmName
662+
Assert-NotNull($recvm.Zones);
663+
664+
$pe = Get-AzRecoveryServicesAsrReplicationProtectedItem -ProtectionContainer $pc -Name $vmName
665+
Assert-NotNull($pe)
666+
667+
#Get Recovery Plan
668+
$RecoveryPlan = Get-AzRecoveryServicesAsrRecoveryPlan -Name $RecoveryPlanName
669+
Assert-NotNull($RecoveryPlan)
670+
}
671+
672+
<#
673+
.SYNOPSIS
674+
Test RecoveryPlanReplication new parametersets
675+
#>
676+
677+
function Test-RecoveryPlanReplication{
678+
param([string] $seed ='918')
679+
$primaryPolicyName = getPrimaryPolicy
680+
$recoveryPolicyName = getRecoveryPolicy
681+
682+
$primaryContainerMappingName = getPrimaryContainerMapping
683+
$recoveryContainerMappingName = getRecoveryContainerMapping
684+
685+
$primaryContainerName = getPrimaryContainer
686+
$recoveryContainerName = getRecoveryContainer
687+
$vaultRgLocation = getVaultRgLocation
688+
$vaultName = getVaultName
689+
$vaultLocation = getVaultLocation
690+
$vaultRg = getVaultRg
691+
$primaryLocation = getPrimaryLocation
692+
$recoveryLocation = getRecoveryLocation
693+
$primaryFabricName = getPrimaryFabric
694+
$recoveryFabricName = getRecoveryFabric
695+
$RecoveryReplicaDiskAccountType = "Premium_LRS"
696+
$RecoveryTargetDiskAccountType = "Premium_LRS"
697+
$policyName = getPrimaryPolicy
698+
$mappingName = getPrimaryContainerMapping
699+
$recMappingName = getRecoveryContainerMapping
700+
$primaryNetMapping = getPrimaryNetworkMapping
701+
$recoveryNetMapping = getRecoveryNetworkMapping
702+
$RecoveryPlanName = getRecoveryPlanName
703+
704+
#create recovery side resources
705+
$recRgName = getRecoveryResourceGroupName
706+
New-AzResourceGroup -name $recRgName -location $recoveryLocation -force
707+
[Microsoft.Rest.ClientRuntime.Azure.TestFramework.TestUtilities]::Wait(20 * 1000)
708+
$RecoveryAzureNetworkId = createRecoveryNetworkId
709+
$index =$RecoveryAzureNetworkId.IndexOf("/providers/")
710+
$recRg =$RecoveryAzureNetworkId.Substring(0,$index)
711+
#create proximity placement group
712+
$recPpg = New-AzProximityPlacementGroup -ResourceGroupName $recRgName -Name "PPG1-asr" -Location $recoveryLocation
713+
$recPpg1 = New-AzProximityPlacementGroup -ResourceGroupName $recRgName -Name "PPG2-asr" -Location $recoveryLocation
714+
715+
#create primary
716+
$vmName = getAzureVmName
717+
New-AzResourceGroup -name $vmName -location $primaryLocation -force
718+
[Microsoft.Rest.ClientRuntime.Azure.TestFramework.TestUtilities]::Wait(20 * 1000)
719+
$logStg = createCacheStorageAccount
720+
$recLogStg = createRecoveryCacheStorageAccount
721+
722+
$v2VmId = createAzureVmInProximityPlacementgroup
723+
$vm = get-azVm -ResourceGroupName $vmName -Name $vmName
724+
$vhdid =$vm.StorageProfile.OSDisk.ManagedDisk.Id
725+
$index =$vm.Id.IndexOf("/providers/")
726+
$Rg =$vm.Id.Substring(0,$index)
727+
$PrimaryAzureNetworkId = $Rg + "/providers/Microsoft.Network/virtualNetworks/" + $vmName
728+
729+
# vault Creation
730+
New-AzResourceGroup -name $vaultRg -location $vaultRgLocation -force
731+
[Microsoft.Rest.ClientRuntime.Azure.TestFramework.TestUtilities]::Wait(20 * 1000)
732+
New-AzRecoveryServicesVault -ResourceGroupName $vaultRg -Name $vaultName -Location $vaultLocation
733+
[Microsoft.Rest.ClientRuntime.Azure.TestFramework.TestUtilities]::Wait(20 * 1000)
734+
$Vault = Get-AzRecoveryServicesVault -ResourceGroupName $vaultRg -Name $vaultName
735+
Set-ASRVaultContext -Vault $Vault
736+
737+
# fabric Creation
738+
$fabJob= New-AzRecoveryServicesAsrFabric -Azure -Name $primaryFabricName -Location $primaryLocation
739+
WaitForJobCompletion -JobId $fabJob.Name
740+
$fab = Get-AzRecoveryServicesAsrFabric -Name $primaryFabricName
741+
Assert-true { $fab.name -eq $primaryFabricName }
742+
Assert-AreEqual $fab.FabricSpecificDetails.Location $primaryLocation
743+
744+
$fabJob= New-AzRecoveryServicesAsrFabric -Azure -Name $recoveryFabricName -Location $recoveryLocation
745+
WaitForJobCompletion -JobId $fabJob.Name
746+
$fab = Get-AzRecoveryServicesAsrFabric -Name $recoveryFabricName
747+
Assert-true { $fab.name -eq $recoveryFabricName }
748+
Assert-AreEqual $fab.FabricSpecificDetails.Location $recoveryLocation
749+
$pf = get-asrFabric -Name $primaryFabricName
750+
$rf = get-asrFabric -Name $recoveryFabricName
751+
752+
#Container creation
753+
$job = New-AzRecoveryServicesAsrProtectionContainer -Name $primaryContainerName -Fabric $pf
754+
WaitForJobCompletion -JobId $Job.Name
755+
$pc = Get-asrProtectionContainer -name $primaryContainerName -Fabric $pf
756+
Assert-NotNull($pc)
757+
$job = New-AzRecoveryServicesAsrProtectionContainer -Name $recoveryContainerName -Fabric $rf
758+
WaitForJobCompletion -JobId $Job.Name
759+
$rc = Get-asrProtectionContainer -name $recoveryContainerName -Fabric $rf
760+
Assert-NotNull($rc)
761+
762+
#create policy and mapping
763+
$job = New-AzRecoveryServicesAsrPolicy -Name $policyName -RecoveryPointRetentionInHours 12 -AzureToAzure
764+
WaitForJobCompletion -JobId $job.Name
765+
$policy = Get-AzRecoveryServicesAsrPolicy -Name $policyName
766+
$job = New-AzRecoveryServicesAsrProtectionContainerMapping -Name $mappingName -Policy $policy -PrimaryProtectionContainer $pc -RecoveryProtectionContainer $rc
767+
WaitForJobCompletion -JobId $job.Name
768+
$mapping = Get-AzRecoveryServicesAsrProtectionContainerMapping -Name $mappingName -ProtectionContainer $pc
769+
770+
#network mapping
771+
$job = New-AzRecoveryServicesAsrNetworkMapping -AzureToAzure -Name $primaryNetMapping -PrimaryFabric $pf -PrimaryAzureNetworkId $PrimaryAzureNetworkId -RecoveryFabric $rf -RecoveryAzureNetworkId $RecoveryAzureNetworkId
772+
WaitForJobCompletion -JobId $job.Name
773+
774+
#enable Replication
775+
$v = New-AzRecoveryServicesAsrAzureToAzureDiskReplicationConfig -managed -LogStorageAccountId $logStg `
776+
-DiskId $vhdid -RecoveryResourceGroupId $recRg -RecoveryReplicaDiskAccountType $RecoveryReplicaDiskAccountType `
777+
-RecoveryTargetDiskAccountType $RecoveryTargetDiskAccountType
778+
$enableDRjob = New-AzRecoveryServicesAsrReplicationProtectedItem -AzureToAzure -AzureVmId $vm.Id -Name $vmName -ProtectionContainerMapping $mapping -RecoveryResourceGroupId $recRg -AzureToAzureDiskReplicationConfiguration $v -RecoveryProximityPlacementGroupId $recPpg.Id
779+
WaitForJobCompletion -JobId $enableDRjob.Name
780+
WaitForIRCompletion -affectedObjectId $enableDRjob.TargetObjectId
781+
782+
#Validate PPG Set in replicated vm properties
783+
$pe = Get-AzRecoveryServicesAsrReplicationProtectedItem -ProtectionContainer $pc -Name $vmName
784+
Assert-NotNull($pe.providerSpecificDetails.RecoveryProximityPlacementGroupId)
785+
786+
#Create Recovery Plan
787+
$createRecoveryJob = New-AzRecoveryServicesAsrRecoveryPlan -Name $RecoveryPlanName -PrimaryFabric $pf -RecoveryFabric $rf -ReplicationProtectedItem $pe
788+
WaitForJobCompletion -JobId $createRecoveryJob.Name
789+
790+
#Get Recovery Plan
791+
$RecoveryPlan = Get-AzRecoveryServicesAsrRecoveryPlan -Name $RecoveryPlanName
792+
Assert-NotNull($RecoveryPlan)
793+
794+
#Failover
795+
$failoverjob = Start-AzRecoveryServicesAsrUnPlannedFailoverJob -RecoveryPlan $RecoveryPlan -Direction PrimaryToRecovery -PerformSourceSideAction
796+
WaitForJobCompletion -JobId $failoverjob.Name
797+
}

0 commit comments

Comments
 (0)