Points clés à retenir (TL;DR)
Synthèse exécutive- Un seul script d'orchestration enchaîne toutes les phases : groupe de ressources, réseau, disque OS, image généralisée, puis VM — chaque phase étant idempotente (rejouable sans effet de bord).
- Le déploiement de la VM est précédé d'un
what-ifet d'une confirmation interactive : rien n'est créé sans visibilité sur l'impact. - On s'appuie sur Bicep pour l'infrastructure déclarative (réseau, VM) et sur Azure CLI pour les actions impératives (upload de VHD, feature registration).
- La VM est créée sans IP publique, avec Gen2/UEFI et les diagnostics de boot activés pour tracer le premier démarrage.
- Une étape post-boot étend le disque OS à sa taille cible depuis l'intérieur de l'invité Linux.

Le probleme qu’on resout
Vous disposez d’une image de machine virtuelle préparée hors Azure (par exemple un VHD adapté depuis une OVA) et vous devez la déployer dans un abonnement Azure, de manière reproductible, dans plusieurs environnements (dev, test, prod) sans dérive de configuration. Le faire « à la main » dans le portail est tentant, mais échoue vite pour trois raisons.
- Enchaînement fragile : réseau, disque, image et VM ont des dépendances. Un oubli d’ordre (créer la VM avant le sous-réseau) casse le déploiement à mi-chemin, laissant des ressources orphelines.
- Non-reproductibilité : les clics manuels ne sont ni versionnés ni documentés. Impossible de rejouer à l’identique ou d’auditer qui a créé quoi.
- Contraintes de plateforme : importer une image généralisée Gen2 avec un type de sécurité « Standard » (Secure Boot désactivé) demande une feature registration au niveau de l’abonnement, étape silencieuse et facile à oublier.
La solution : un script d’orchestration unique, découpé en phases idempotentes, avec un garde-fou (what-if + confirmation) avant la seule action coûteuse et difficile à annuler, la création de la VM.
Comment ca marche
L’approche sépare deux natures d’opérations. Les ressources dont l’état final est connu (réseau, VM) sont décrites en Bicep et déployées via az deployment group create : Azure réconcilie l’état désiré, donc rejouer le déploiement ne recrée rien d’inutile. Les actions impératives — transfert du VHD vers un disque managé, création d’une image généralisée, enregistrement d’une fonctionnalité d’abonnement — passent par Azure CLI dans des sous-scripts dédiés.
Points de conception importants :
- Idempotence :
group createetdeployment group createpeuvent être relancés ; les scripts d’upload vérifient l’existence avant d’agir. - Gen2 / UEFI : l’image source est en génération 2. Le type de sécurité « Standard » (Secure Boot OFF) convient quand l’image n’est pas compatible Trusted Launch ; il faut activer la fonctionnalité correspondante une seule fois par abonnement.
- Pas d’IP publique : l’accès se fait par réseau privé (VPN, bastion ou peering). La console série et les diagnostics de boot permettent de dépanner un premier démarrage sans exposer la VM.
- Disque OS en Standard_LRS (HDD) pour un environnement non-critique de type dev : coût minimal, à ajuster en Premium_LRS pour la production.
Prerequis
- Un abonnement Azure et un rôle Contributor sur le groupe de ressources cible (ou au niveau abonnement pour la feature registration).
- Azure CLI (localement ou dans un conteneur dédié) authentifié via
az loginou une identité managée / principal de service. - Le VHD source adapté (Gen2, généralisé avec
sysprepou l’équivalent Linuxwaagent -deprovision) accessible depuis la machine qui exécute le script. - Les fichiers Bicep du réseau et de la VM, plus leurs fichiers de paramètres
.bicepparam. - Les fournisseurs de ressources
Microsoft.ComputeetMicrosoft.Networkenregistrés sur l’abonnement. - Une fenêtre de changement validée si le déploiement cible un environnement partagé.
Procedure
- Créer (ou garantir l’existence) du groupe de ressources dans la région choisie.
- Déployer le réseau : VNet, sous-réseau d’administration et groupe de sécurité réseau (NSG) via Bicep.
- Transférer le VHD vers un disque managé OS (HDD) — phase impérative via CLI.
- Créer l’image généralisée Gen2 à partir de ce disque.
- Enregistrer la fonctionnalité de type de sécurité Standard si l’image n’est pas compatible Trusted Launch (une fois par abonnement).
- Lancer un
what-ifsur le déploiement de la VM, lire attentivement le delta, puis confirmer. - Activer les diagnostics de boot et consulter le journal du premier démarrage.
- Après le boot, se connecter (console série ou SSH par réseau privé) et étendre le disque OS à sa taille cible.
Le script
Script d’orchestration générique. Toutes les valeurs sont des exemples à adapter ; aucune donnée propre à une organisation n’y figure.
#!/usr/bin/env bash
# =====================================================================
# Orchestration d'un deploiement Azure complet depuis un VHD prepare.
# Phases idempotentes ; la VM est precedee d'un what-if + confirmation.
# Valeurs d'exemple : a adapter a votre environnement.
# =====================================================================
set -euo pipefail
# --- Variables (exemples generiques) ---------------------------------
DEPLOY_DIR="$HOME/deploy-azure" # dossier contenant les .bicep
AZ="az" # ou "docker exec az-cli az" si conteneurise
RG="rg-app-dev" # groupe de ressources cible
LOC="canadacentral" # region Azure
VM_NAME="vm-app-dev" # nom de la VM
echo "### 0. Groupe de ressources (idempotent)"
$AZ group create -n "$RG" -l "$LOC" -o none
echo "### 1. Reseau : VNet + sous-reseau admin + NSG"
$AZ deployment group create -g "$RG" -n deploy-reseau \
--template-file "$DEPLOY_DIR/reseau.bicep" -o none
echo " -> reseau OK"
echo "### 2. Disque OS depuis le VHD prepare (HDD)"
bash "$DEPLOY_DIR/phase-upload-disque.sh" # upload du VHD vers un disque manage
echo "### 3. Image generalisee Gen2"
bash "$DEPLOY_DIR/phase-image.sh" # creation de l'image a partir du disque
echo "### 4. Fonctionnalite securityType=Standard (Secure Boot OFF)"
echo " (a executer une seule fois par abonnement)"
$AZ feature register --namespace Microsoft.Compute \
--name UseStandardSecurityType -o none || true
$AZ provider register -n Microsoft.Compute -o none || true
echo "### 5. VM : what-if puis creation sur confirmation"
$AZ deployment group what-if -g "$RG" \
--template-file "$DEPLOY_DIR/vm.bicep" \
--parameters "$DEPLOY_DIR/vm.bicepparam"
read -r -p " Deployer la VM maintenant ? [o/N] " reponse
[ "${reponse:-N}" = "o" ] || { echo " (annule)"; exit 0; }
$AZ deployment group create -g "$RG" -n "deploy-$VM_NAME" \
--template-file "$DEPLOY_DIR/vm.bicep" \
--parameters "$DEPLOY_DIR/vm.bicepparam" -o none
echo "### 6. Diagnostics de boot"
$AZ vm boot-diagnostics enable -g "$RG" -n "$VM_NAME" -o none || true
echo " Journal de boot :"
echo " $AZ vm boot-diagnostics get-boot-log -g $RG -n $VM_NAME"
cat <<'FIN'
=== Apres le boot, dans la VM, etendre le disque OS a la taille cible : ===
sudo growpart /dev/sda 3
sudo pvresize /dev/sda3
sudo lvextend -l +100%FREE /dev//
sudo resize2fs /dev//
=== Termine. Toute reservation de capacite est un geste SEPARE, apres validation. ===
FIN
Variante : pour forcer un déploiement non interactif (pipeline CI/CD), remplacez le bloc read par une variable d’environnement contrôlée.
# Mode non interactif : n'activer que dans un pipeline maitrise
if [ "${AUTO_CONFIRM:-false}" = "true" ]; then
reponse="o"
else
read -r -p " Deployer la VM maintenant ? [o/N] " reponse
fi
Validation
Après chaque phase, vérifiez l’état réel plutôt que de supposer le succès :
- Réseau :
az network vnet list -g rg-app-dev -o tableetaz network nsg list -g rg-app-dev -o tabledoivent retourner vos ressources. - Disque et image :
az disk list -g rg-app-dev -o tableetaz image list -g rg-app-dev -o table. - Déploiement VM :
az deployment group show -g rg-app-dev -n deploy-vm-app-dev --query properties.provisioningState -o tsvdoit renvoyerSucceeded. - État de la VM :
az vm get-instance-view -g rg-app-dev -n vm-app-dev --query "instanceView.statuses[1].displayStatus" -o tsvdoit afficherVM running. - Boot :
az vm boot-diagnostics get-boot-log -g rg-app-dev -n vm-app-devdoit montrer une séquence de démarrage saine (chargement du noyau, montage du système de fichiers racine, invite de login). - Extension du disque : dans l’invité,
df -h /doit refléter la taille cible aprèsresize2fs.
Plan de retour (rollback)
La force du modèle idempotent : le rollback est propre et ciblé.
- Annulation complète (déploiement dev jetable) : supprimez le groupe de ressources entier avec
az group delete -n rg-app-dev --yes --no-wait. Toutes les ressources créées par le script disparaissent. - Annulation ciblée de la VM :
az vm delete -g rg-app-dev -n vm-app-dev --yes, puis supprimez le disque OS et la carte réseau associés si vous souhaitez repartir de l’image. - Avant toute suppression en environnement partagé : capturez un instantané du disque OS (
az snapshot create) pour pouvoir recréer la VM à l’identique. - La feature registration de type de sécurité est bénigne et peut rester : elle n’impacte pas les ressources existantes.
Depannage
| Symptome | Cause probable | Solution |
|---|---|---|
| La création de la VM échoue sur le type de sécurité | Fonctionnalité UseStandardSecurityType non enregistrée ou pas encore propagée |
Vérifier az feature show --namespace Microsoft.Compute --name UseStandardSecurityType ; attendre l’état Registered puis relancer az provider register -n Microsoft.Compute |
| Déploiement réseau en erreur de dépendance | Sous-réseau ou NSG référencé avant création | Corriger l’ordre dans le Bicep ou utiliser dependsOn explicite ; relancer la phase (idempotente) |
| La VM démarre mais reste inaccessible | Absence d’IP publique et pas de route privée configurée | Utiliser la console série Azure ou un bastion ; vérifier les règles du NSG et le peering/VPN |
| Boot bloqué / écran noir dans les diagnostics | Image non généralisée correctement ou incompatibilité Gen2 | Regénéraliser l’image source (deprovision), confirmer hyperVGeneration=V2 sur l’image |
| Le disque reste à sa taille initiale après boot | Partition et LVM non étendus dans l’invité | Exécuter growpart, pvresize, lvextend puis resize2fs |
az deployment group create échoue en authentification |
Session CLI expirée ou droits insuffisants | Relancer az login ; vérifier le rôle Contributor sur le groupe de ressources |
Securite, changement et bonnes pratiques
- Moindre privilège : attribuez le rôle Contributor au périmètre le plus étroit (le groupe de ressources), pas l’abonnement, sauf pour l’enregistrement initial de la fonctionnalité.
- Pas de secrets en clair : ne stockez jamais de mot de passe ou de clé dans les
.bicepparamversionnés. Utilisez des clés SSH, Azure Key Vault ou des références sécurisées (@secure()en Bicep). - Surface d’attaque réduite : absence d’IP publique par défaut, NSG restrictif, accès par bastion ou réseau privé uniquement (MITRE ATT&CK T1133 — services distants externes à éviter).
- Trusted Launch de préférence : le type Standard (Secure Boot OFF) est un compromis pour les images non compatibles ; privilégiez Trusted Launch dès que l’image le permet.
- Idempotence et versionnage : stockez les Bicep et le script dans un dépôt Git ; chaque exécution doit être traçable et rejouable.
- Cadrage ITIL : un premier déploiement en environnement partagé est un changement normal soumis au CAB ; un redéploiement répétable et documenté en dev peut être traité comme changement standard pré-approuvé. Planifiez la création de VM dans une fenêtre de maintenance, documentez le plan de retour dans la fiche de changement, et conservez les journaux de déploiement comme preuve.
A retenir
Orchestrer un déploiement Azure par script transforme une série de clics fragiles en un processus reproductible, idempotent et auditable. La clé est la séparation entre déclaratif (Bicep pour le réseau et la VM) et impératif (CLI pour l’image), avec un what-if et une confirmation avant la seule action coûteuse. Le résultat : des environnements identiques d’un déploiement à l’autre, un rollback propre et une traçabilité conforme aux attentes ITIL.
Commencez par un environnement de dev jetable, validez le boot et l’extension du disque, puis promouvez le script vers vos environnements supérieurs en ajustant le type de disque et le niveau de sécurité. Versionnez tout, et faites relire vos Bicep avant la première exécution en production.