Archives mensuelles : février 2019

Migrer une machine virtuelle entre régions Azure

Voilà un cas client qui m’a occupé un certain temps. Mon client déploie une application basée sur des services IaaS à l’aide d’images préalablement générées. Mes images « sources » sont localisées dans la région Azure France Central et doivent être mise à disposition dans la région Brazil South. Voilà pour le besoin de base.

Mon premier réflexe a été de rechercher si un service de réplication d’images n’existait pas. On a bien un repository pour les images pour les conteneurs (Azure Contrainer Registry), on doit donc avoir le même type de service pour le IaaS. C’est effectivement le cas, cela se nomme Shared Image Gallery. Mais, j’ai tout de suite exclu ce choix car :

  • Service actuellement en Preview
  • Pas encore disponible dans les régions Azure qui me concernent

Second réflexe, Azure Site Recovery. Cela fait quelques temps que l’on peut utiliser le service pour « cloner » une machine virtuelle existante pour assurer un DRP vers une autre région Azure. Très rapidement, j’ai dû abandonner cette option car les régions Azure source et destination ne dépendent pas du même cluster géographique.

clip_image001

Source : https://docs.microsoft.com/en-us/azure/site-recovery/azure-to-azure-support-matrix

Pire, le cas de la région Azure Brazil South est un peu particulier car au sein de son Géo, il n’a pas de région Azure associée. Bref, pas la bonne solution.

En dernier ressort, je suis tombé sur cet article : Synchronously copy all managed disks of an Azure Virtual Machine to Azure Storage Accounts in multiple Azure regions. C’est presque ce qu’il me faut car il faudra reconstruire une image après. A mes yeux, la démarche proposée avait quelques défauts :

  • On paie une VM pour faire la copie avec AZCopy alors qu’on peut faire un job de copie
  • Elle est un peu salée la VM en SKU E pour de la copie de fichiers
  • Les opérations sont réalisées en séquentielle alors qu’on se contente de suivre un job.

J’avais déjà publié un billet pour cloner des machines virtuelles dans Azure. J’ai donc juste poussé la logique d’industrialisation jusqu’au bout. Cela va se dérouler en plusieurs étapes :

  • Etape n°1 : Initialisation
  • Etape n°2 : Génération des clés SAS pour les VHD
  • Etape n°3 : Initialisation des opérations de copie
  • Etape n°4 : Suivi des opérations de copie
  • Etape n°5 : Reconstruction des Managed Disks

 

Etape n°1 : Initialisation

Avant de commencer, on va poser quelques bases. J’ai déployé une machine virtuelle en utilisant mon image dans le groupe de ressources « FranceCentral ». L’objectif est d’obtenir des Managed Disks dans le groupe de ressources « BrazilSouth » dans lequel on va préalablement avoir créé un Storage Account qui va être utilisé pour réceptionner les VHD à copier.

$SourceResourceGroup = « FranceCentral »

$SourceVMName = « MASTER »

$dataDiskNames = New-Object System.Collections.ArrayList

$dataDiskSASes = New-Object System.Collections.ArrayList

$SasKeyDuration = 36000

$DestinationResourceGroup = « BrazilSouth »

$DestinationStorageAccount = « brazilreplication »

$Accounttype = ‘Standard_LRS’

$VM = Get-AzureRmVM -ResourceGroupName $SourceResourceGroup -Name $SourceVMName -Verbose

clip_image002

 

Etape n°2 : Génération des clés SAS pour les VHD

Pour chaque disque composant notre machine virtuelle, nous devons générer une clé SAS. J’ai volontairement configuré une durée de vie assez longue, ne voulant pas tomber dans une situation ou les clés SAS auraient échouées pour cause d’une copie beaucoup trop longue.

$osDiskName = $VM.StorageProfile.OsDisk.Name

$osDiskSAS = (Grant-AzureRmDiskAccess -Access Read -DiskName $osDiskName -ResourceGroupName $SourceResourceGroup -DurationInSecond $SasKeyDuration -Verbose).AccessSAS

foreach($dataDisk in $VM.StorageProfile.DataDisks)

{

$dataDiskNames.Add($dataDisk.Name) | Out-Null

}

foreach($dataDiskName in $dataDiskNames)

{

$dataDiskSASes.Add((Grant-AzureRmDiskAccess -Access Read -DiskName $dataDiskName -ResourceGroupName $SourceResourceGroup -DurationInSecond $SasKeyDuration -Verbose).AccessSAS) | Out-Null

}

clip_image003

 

A ce stade, si on observe un des objets Managed Disks dans le portail, on peut constater qu’une clé SAS a bien été générée pour chacun d’eux.

clip_image004

 

Etape n°3 : Initialisation des opérations de copie

C’est en ce point que je me suis différencié de l’article Synchronously copy all managed disks of an Azure Virtual Machine to Azure Storage Accounts in multiple Azure regions. Mon besoin n’étant pas de répliquer mes disques dans de multiples régions, pas besoin d’autant d’instance de la machine virtuelle Ubuntu pour réaliser les opérations de copies. En plus, on n’a pas besoin d’attendre. Ça fait bien longtemps qu’AZCopy.EXE supporte la notion de job pour les opérations de copies. En PowerShell, AZCOPY.EXE, c’est Start-AzureStorageBlobCopy. A ce stade, du contenu va commencer à apparaître dans le contenu prévu à cet effet dans le Storage Account localisé dans la région cible.

$DestStorageAccountKeys = Get-AzureRmStorageAccountKey -ResourceGroupName $DestinationResourceGroup -Name $DestinationStorageAccount

$DestStorageContext = New-AzureStorageContext -StorageAccountName $DestinationStorageAccount -StorageAccountKey $DestStorageAccountKeys[0].Value

Start-AzureStorageBlobCopy -AbsoluteUri $osDiskSAS -DestContainer $SourceVMName.ToLower() -DestContext $DestStorageContext -DestBlob $($osDiskName + « .VHD »)

$DatadiskCount = 0

foreach($dataDiskSAS in $dataDiskSASes)

{

Start-AzureStorageBlobCopy -AbsoluteUri $dataDiskSAS -DestContainer $SourceVMName.ToLower() -DestContext $DestStorageContext -DestBlob $(« datadisk-$DatadiskCount » + « .VHD »)

$DatadiskCount +=1

}

clip_image005

 

Etape n°4 : Suivi des opérations de copie

La commande PowerShell Start-AzureStorageBlobCopy initié un job que l’on va suivre. Avantage, on va paralléliser toutes les opérations de copie. Pour suivre cela, on dispose de la commande PowerShell Get-AzureStorageBlobCopyState. La durée des opérations de copie dépendra principalement de la volumétrie de données à répliquer. Pour mes tests, quarante-neuf minutes étaient nécessaires pour répliquer un Managed Disk SATA de 127Go et un autre de 1To.

$StartTime = Get-Date

$StorageOperations = Get-AzureStorageBlob -Container master -Context $DestStorageContext | Get-AzureStorageBlobCopyState

While ($StorageOperations | Where-Object {$_.status -eq « Pending »})

{

$StorageOperations | select-Object Copyid, Status

Start-Sleep -Seconds 10

$StorageOperations = Get-AzureStorageBlob -Container master -Context $DestStorageContext | Get-AzureStorageBlobCopyState

}

$CopyTimeSpan = New-TimeSpan -Start $StartTime -End (Get-Date)

$Totalcopyoperations ='{0:N0}’ -f $($CopyTimeSpan.TotalMinutes)

Write-Host « Copy operation completed in $Totalcopyoperations minutes. »

clip_image006

 

Etape n°5 : Reconstruction des Managed Disks

Il ne nous reste plus qu’à reconstruire des Managed Disks en commençant par construire un objet de type Managed Disk à l’aide de la commande PowerShell New-AzureRmDiskConfig. De, là, il n’y a plus qu’à créer la ressource Azure à l’aide de la commande PowerShell New-AzureRmDisk.

$Container = Get-AzureStorageContainer -Container master -Context $DestStorageContext

$ContainerBaseURI = ($Container.CloudBlobContainer).uri.absoluteuri

$ListVHDs = Get-AzureStorageBlob -Container master -Context $DestStorageContext

ForEach ($VHD in $ListVHDs)

{

$Disksize = ($vhd.Length/1GB) +1

$Vhduri = $ContainerBaseURI + « / » + $vhd.name

$diskName = ($vhd.name).Substring(0, ($vhd.name).lastindexof(« . »))

Write-Host « Creating Managed Disk $diskName in Resource Group $DestinationResourceGroup. »

$diskConfig = New-AzureRmDiskConfig -AccountType $Accounttype -Location ((get-azurermresourcegroup -Name $DestinationResourceGroup).location) -DiskSizeGB $Disksize -SourceUri $vhdUri -CreateOption Import

New-AzureRmDisk -DiskName $diskName -Disk $diskConfig -ResourceGroupName $DestinationResourceGroup

}

clip_image007

 

Maintenant, il y a plus qu’à reconstruire l’image de référence au brésil et supprimer les fichiers VHD.

 

Conclusion

La solution n’est pas parfaite, elle peut encore être améliorée. Si vous être plus de culture Linux, allez lire ce billet : Copy custom vm images on azure. L’approche est sensiblement identique.

 

Benoît – Simple and Secure by design but Business compliant.