Sauvegarde des disques de VM via Runbook/Snapshot

Sauvegarder ou ne pas sauvegarder ? Telle est la question ! Évidemment, la sauvegarde n’est pas un choix mais bien une nécessité ! Dans cet article, nous allons prendre le temps de nous intéresser aux sauvegardes de machines virtuelles dans un cas très particulier.

Cet article n’a pas pour but de vous parler de la sauvegarde native des machines virtuelles sous Azure, via le service Azure Recovery Service Vault. Cette fonctionnalité est à la portée de tous et fonctionne sans souci.

Mais il arrive dans certains cas que ce service ne fonctionne pas pour certaines machines virtuelles… Voici par exemple le déploiement d’un firewall Fortigate, disponible sur la marketplace d’Azure

Une fois cette machine virtuelle déployée, j’ai rajouté des disques de données supplémentaires à cette dernière

J’ai ensuite créé un Recovery Service Vault pour mettre en place une sauvegarde habituelle

J’ai continué avec la configuration de la police de sauvegarde avec ma machine virtuelle

Seulement l’activation de la sauvegarde Azure me pose quelques soucis

Voici le détail du message d’erreur

{
    "status": "Failed",
    "error": {
        "code": "UserErrorUnSupportedDistribution",
        "message": "Unsupported OS version for virtual machine backup."
    }
}

Ce problème est visiblement connu sur la toile depuis plusieurs années, mais pour l’instant aucune alternative n’a été proposée par Microsoft. Inutile de penser aux agents MARS ou MABS…

Que faire dans ce cas ?

Il est bien possible de faire des snapshots réguliers … à la main !

En quête d’automatisation, je suis tombé sur plusieurs articles intéressants, assez proche sur la solution apportée :

Qu’est-ce qu’Azure Automation ?

Azure Automation est un service d’automatisation et de configuration basé sur le cloud qui prend en charge la gestion cohérente de vos environnements Azure et non-Azure. Il comprend l’automatisation des processus, la gestion des configurations, la gestion des mises à jour, les capacités partagées et les fonctionnalités hétérogènes. L’automatisation vous donne un contrôle total pendant le déploiement, l’exploitation et la mise hors service des charges de travail et des ressources.

Yst@IT
Merci Travis !

Dans notre déploiement, nous allons utiliser un compte Azure Automation pour stocker et lancer notre script PowerShell. Ce script prend en compte les disques rattachés à la machine virtuelle afin d’en faire des snapshots pour chacun d’eux.

Etape 0 : Rappel des prérequis

Passé cette rapide explication, nous allons créer différentes ressources sur Azure pour y parvenir. Comme toujours, des prérequis sont nécessaires pour réaliser cette démonstration :

  • Un tenant Microsoft
  • Une souscription Azure valide
  • Une machine virtuelle déployée

Etape I : Affectation d’un tag sur la machine virtuelle

Le script va effectuer une recherche sur les machines virtuelles à sauvegarder. Il est nécessaire de marquer celles qui nous intéresse. Rendez-vous sur la machine virtuelle concernée et ajoutez-y le tag suivant :

  • Nom : Snapshot
  • Valeur : True

Etape II : Création du compte Azure Automation

Tout commence par la création d’un compte Azure Automation pour héberger notre script PowerShell. Utilisez la barre de recherche du portail Azure pour commencer éa création

Renseignez les éléments de base sur le premier onglet du compte puis lancez directement la création de celui-ci :

Cherchez la section Paramétrages du compte, puis cliquez sur Identité et enfin assignez les rôles Azure

Ajoutez le rôle de Contributeur sur le groupe de ressources contenant la machine virtuelle, puis sauvegardez

Quelques minutes plus tard, constatez la présence de ce dernier dans le tableau précédent

Etape III : Création du Runbook

Continuez avec la création de votre runbook

Renseignez les champs pour valider sa création

La création vous ouvre ensuite l’éditeur de code

Collez le script suivant dans l’éditeur, ou également disponible sur mon GitHub

# Use Managed Identity
Connect-AzAccount -Identity

# Get VMs with snapshot tag
$tagResList = Get-AzResource -TagName "Snapshot" -TagValue "True" | foreach {
Get-AzResource -ResourceId $_.resourceid
}

foreach($tagRes in $tagResList) {
if($tagRes.ResourceId -match "Microsoft.Compute")
{
$vm = Get-AzVM -ResourceGroupName $tagRes.ResourceId.Split("//")[4] -Name $tagRes.ResourceId.Split("//")[8]
#Set local variables
$location = $vm.Location
$resourceGroupName = $vm.ResourceGroupName
$vmname = $vm.Name

# Generate OS snapshot configuration
$snapshotName = $vm.StorageProfile.OsDisk.Name + $(get-date -Format 'yyyy-MM-dd-m')
$snapshot =  New-AzSnapshotConfig `
-SourceUri $vm.StorageProfile.OsDisk.ManagedDisk.Id `
-Location $location `
-CreateOption copy

# Create OS snapshot
New-AzSnapshot `
-Snapshot $snapshot `
-SnapshotName $snapshotName `
-ResourceGroupName $resourceGroupName

# Add SnapshotTags
$tags = (Get-AzResource -ResourceGroupName $resourceGroupName -Name $snapshotName).Tags
$tags += @{Location="$location"; Vm="$vmname"; SnapshotDate="$(get-date -Format 'yyyy-MM-dd-m')"; Script="JLOScript"}
Set-AzResource `
-ResourceGroupName $resourceGroupName `
-Name $snapshotName `
-ResourceType "Microsoft.Compute/snapshots" `
-Tag $tags `
-Force

# Generate DATA snapshot configuration
if($vm.StorageProfile.DataDisks.Count -ge 1){

#Condition with more than one data disks
for($i=0; $i -le $vm.StorageProfile.DataDisks.Count - 1; $i++){

# Generate snapshot configuration
$snapshotName = $vm.StorageProfile.DataDisks[$i].Name + $(get-date -Format 'yyyy-MM-dd-m')
$snapshot =  New-AzSnapshotConfig `
-SourceUri $vm.StorageProfile.DataDisks[$i].ManagedDisk.Id `
-Location $location `
-CreateOption copy

# Create snapshot
New-AzSnapshot `
-Snapshot $snapshot `
-SnapshotName $snapshotName `
-ResourceGroupName $resourceGroupName

# Add SnapshotTags
$tags = (Get-AzResource -ResourceGroupName $resourceGroupName -Name $snapshotName).Tags
$tags += @{Location="$location"; Vm="$vmname"; SnapshotDate="$(get-date -Format 'yyyy-MM-dd-m')"; Script="JLOScript"}
Set-AzResource `
-ResourceGroupName $resourceGroupName `
-Name $snapshotName `
-ResourceType "Microsoft.Compute/snapshots" `
-Tag $tags `
-Force
}
}

else{
Write-Host $vmInfo.Name + " doesn't have any additional data disk."
}
}

else{
$tagRes.ResourceId + " is not a compute instance"
}
}

Etape IV : Test du Runbook

Sauvegardez votre code et lancez un test

Cliquez sur le bouton ci-dessous pour démarrer le test

Attendez un peu

Constatez le succès ou l’échec de votre runbook

Retournez sur le groupe de ressources pour y voir apparaître les snapshots des disques

Cliquez sur l’un d’eux et constatez les tags

Etape V : Mise en place de l’automatisation

Une fois constaté le succès de votre script, il ne vous reste qu’à le publier et à le programmer périodiquement. Retournez sur votre runbook et cliquez sur Publier

Ajoutez une programmation périodique sur votre runbook

Cliquez sur le premier lien

Cliquez sur ajouter une programmation

Renseignez les champs selon votre besoin

Confirmez la bonne création de votre programmation

Contrôlez au prochain lancement de la programmation dans le groupe de ressources

Contrôlez également l’historique des lancements du runbook

Conclusion

Et voilà ! Une tâche manuelle de moins… Cette petite opération nous a permis de bien comprendre l’utilité et la puissance des automatismes possibles sur Azure. Celui-ci est bien évidemment très simple, d’autres sont sans doute très intéressants à mettre en oeuvre 😊.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée.