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 😊.

Changer la taille du disque OS sur une machine virtuelle via [smalldisk] / Resize

Azure VM | Microsoft Power Automate

Des machines virtuelles sont créées en permanence sur Azure, et très régulièrement sur Windows Serveur. Sans se poser de question, le choix de l’image présélectionne sans votre avis la taille du disque OS, sans aucun pouvoir de modification.

Mais comment faire si l’on souhaite autre chose que la taille par défaut de 128GB pour notre lecteur C ?

Nous allons voir ensemble dans cet article les différentes possibilités, avant et après la création d’une machine virtuelle, pour changer très facilement la taille du disque OS.

Cas classique : Image Windows Server

Commençons par le cas standard, la création d’une machine virtuelle avec Windows Serveur entraîne la création d’un disque OS.

Sélectionnons ici par exemple une image source Windows Server 2019.

Dans le second onglet de création de la machine virtuelle, je n’ai pas de choix concernant la taille de mon disque OS :

Cet onglet me propose de choisir les performances du disque OS, mais pas sa taille. La taille est par contre bien un choix disponible sur les disques de données ajoutés.

Rappel : les performances du disque vont influer sur la SLA de la machine virtuelle, que vous pouvez retrouver en pourcentages ici.

Une fois la machine virtuelle créée, je ne peux que constater la taille de mon disque OS, assez facilement depuis la section des disques :

Un clique sur le disque OS vous amène sur sa page dédiée.

Redimensionnement du disque OS sur une machine virtuelle existante

Une alerte est mentionnée en haut de page : la taille d’un disque ne peut se faire que si ce dernier est détaché de la machine virtuelle ou que si cette dernière est éteinte :

Cas A : Redimensionnement à la baisse

Une fois la machine virtuelle arrêtée, un redimensionnement à la baisse va obligatoirement échouer, dans le but de prévenir la perte de données :

Erreur remontée par Azure au moment du redimensionnement à la baisse.

Cas B : Redimensionnement à la hausse

Cela ne sera pas le cas dans le cas d’un redimensionnement à la hausse, comme vous pouvez le voir en dessous :

La taille du disque OS a bien été augmentée. Notez que le nombre max d’IOPS a aussi fait un bon.

Dernière chose à faire, agrandir la partition du lecteur C directement depuis la machine virtuelle :

Comment faire donc pour effectuer pour disposer d’un lecteur C plus petite taille ? Sachant que l’OS est loin de remplir le lecteur C, plusieurs options s’offrent à nous :

  • Création d’une machine virtuelle avec une image portant la mention [smalldisk]
  • Redimensionnement du disque OS, après déploiement de la machine virtuelle

Remarque importante : Prenez garde avec la taille des disques, un disque trop réduit vous apportera peu d’IOPS et donc des performances disques insuffisantes :

Néanmoins, cette démarche peut être utile dans certains cas et donc générer une économie de coûts.

1er cas : Image Windows Server 2019 [smalldisk]

Si, avant la création de la machine virtuelle, vous savez déjà que votre disque C peut être plus réduit, vous pouvez alors partir sur des images spécifiques. Voici par exemple la liste des [smalldisk] disponibles pour Windows Serveur :

Si vous avez des difficultés de visualisation du nom complet des images, un passage du curseur sur un choix vous donnera son nom complet.

Une fois la machine provisionnée sur votre souscription Azure, vous constaterez que la taille du disque OS est de 30GB. Cette taille est donc plus réduite que la précédente. Vous pourrez toujours changer celle-ci à la hausse simplement en éteignant votre machine virtuelle.

Notez qu’une taille custom du disque entraine toujours une facturation égale à la taille supérieure : ici 32GB.

2ème cas : Redimensionnement du lecteur C puis du disque OS

Il arrive dans certains cas que la machine virtuelle existe déjà. Il va donc falloir commencer le processus par redimensionner le lecteur C. Je suis donc tombé sur cet excellent article (en anglais) et écrit par Jack Rudlin. Les étapes nécessaires pour y parvenir sont :

  • Réduction de la partition de l’OS dans Windows
  • Redimensionnement du disque OS dans Azure
  • Lancement du script sous PowerShell
  • Extension de la partition du système d’exploitation

Je recréé donc une nouvelle machine virtuelle, afin de faire avec vous cette opération de réduction « à chaud » :

Comme indiqué ici, la taille custom de mon disque OS est de 127GB.

Important : comme indiqué dans l’article de Jack et dans la source Microsoft, il est fortement recommandé de faire un snapshot du disque avant toute opération pour sauvegarder les données.

Dans un premier temps, nous nous connectons en RDP sur la machine virtuelle. Cet accès nous permet de changer la taille du lecteur C via un une première requête PowerShell, disposants des droits d’administration :

Get-Partition -DiskNumber 0

Cette requête nous donne le numéro de partition, utilisé après pour le redimensionnement.
La requête ci-dessus prend en compte le numéro du disque pour nous présenter les partitions associées.

Get-Partition -DiskNumber 0 -PartitionNumber 2 | Resize-Partition -Size 31GB

Cette simple commande redimensionne la partition du lecteur C.
L’effet de la requête est immédiatement visible 🙂
Existing Volumes
Comme indiqué sur le blog de Jack, vous pouvez rencontrer une erreur si la taille visée est trop petite.

La suite va se faire en dehors de la machine virtuelle. Il faut commencer par éteindre la machine virtuelle pour effectuer la copie des données :

Machine virtuelle arrêtée et dont les ressources ne sont plus allouées. Rappel : une désallocation des ressources entraînent un forte disque de perte des données disque D : temporaire.

Il donc falloir ici utiliser le module AZ sur votre poste via PowerShell pour continuer la suite des opérations. Voici une vidéo qui explique bien comment y arriver facilement :

Merci à David Lamb 🙂

La suite se fait avec le lancement du script donné par Jack, disponible depuis son GitHub via ce lien.

Aussi je vous conseille de passer par PowerShell ISE pour modifier facilement le script, car plusieurs variables vont devoir être modifiées :

  • Ressource ID du disque OS à modifier, que vous pouvez retrouver dans les propriétés du disque OS
  • Nom de la VM, que vous pouvez retrouver sur la page de la machine virtuelle
  • Nom de la souscription Azure, que vous pouvez retrouver sur la page de la machine virtuelle
Ressource ID du disque OS que vous pouvez retrouver dans les propriétés du disque OS.
Nom de la VM que vous pouvez retrouver sur la page de la machine virtuelle.
Nom de la souscription Azure que vous pouvez retrouver sur la page de la machine virtuelle.

Avant de lancer le script :

  • Celui-ci demande de posséder un certains nombres de droits pour effectuer toutes les tâches
  • Dans mon exemple (généralement non recommandé), j’ai utilisé un utilisateur avec le profil d’administrateur global du tenant Azure
  • A minima, vous devez disposer au moins des rôles de contributeur VM et de contributeur de compte de stockage dans Azure

Dans le détail, le script de Jack effectue les actions suivantes :

  • Création d’un compte de stockage temporaire
  • Création d’un container temporaire dans le nouveau compte de stockage
  • Copie du disque OS dans le compte de stockage temporaire sous forme de page blob
  • Modification la taille du page blob pour que le disque d’OS soit réduit
  • Reconversion du disque non managé en disque managé
  • Remplacement du disque OS actuel de la VM par le nouveau disque OS plus petit
  • Redémarrage de la machine virtuelle
  • Nettoyage du compte de stockage temporaire et de l’ancien disque managé

Le processus peut également être suivi depuis le portail Azure en constatant l’évolution du compte de stockage créé par le script de Jack :

Compte de stockage temporaire créé par le script.
Copie du disque OS en disque non managé (page blob).
Copie du disque non managé sur un second avec une taille réduite.
Suppression du page blob ayant la taille originale.
Un nouveau disque managé est créé à partir du dernier page blob et porte la mention « -new ».
Suppression du dernier page blob une fois la transformation faite en disque managé.
Comme on le constate sur la machine virtuelle utilisée dans mon exemple, le script détache l’ancien disque OS et rattache aussi le disque OS à taille réduite.
La machine virtuelle est redémarrée automatiquement par le script.
Suppression du compte de stockage temporaire en fin de script.

Il faut compter une bonne quinzaine de minutes pour que le script arrive à sa fin. Une connexion en RDP à cette dernière permet de réaliser la dernière étape du processus.

Compte tenu des volumes renseignés dans notre exemple, un reliquat d’espace est disponible sur le disque OS (522MB) :

Ce surplus peut être réintégré sur le lecteur C, comme indiqué sur cette image.
Fin de l’opération 🙂

Il faut donc compter au total une bonne vingtaine de minutes pour effectuer ce processus.

Conclusion

Il est donc bien possible de redimensionner un disque OS à plusieurs moments. Pensez toujours à faire des sauvegardes avant ce type d’opération ! Pensez à partager dans les commentaires vos autres sources d’apprentissage 😋