Cette architecture utilise un VNet Hub comme point central de sécurité et deux VNets Spokes pour les ressources applicatives.
- Sécurité : Azure Firewall (inspection du trafic inter-spoke).
- Accès : Azure Bastion (pas d'IP publiques sur les VMs).
- Routage : Tables de routage personnalisées (UDR) pour forcer le passage par le Firewall.
Avant de commencer, ouvrez votre terminal PowerShell, connectez-vous à votre compte Azure (az login) et définissez les variables globales :
# Nom du Groupe de Ressources (Conteneur logique pour toutes les ressources)
$RG = "RG-HUB-SPOKE-PROJECT"
# Région Azure de déploiement (Norvège Est - choisi pour la conformité et les quotas)
$Loc = "norwayeast"
# Identifiant administrateur pour les Machines Virtuelles (VMs)
$AdminUser = "azure_admin"
# Mot de passe administrateur complexe (Doit respecter les exigences de sécurité Azure)
$AdminPass = "Enterprise@Secure2025!"
Write-Host "--- Étape 1 : Création du Groupe de Ressources ---" -ForegroundColor Cyan
az group create --name $RG --location $Loc
# --name $RG : Utilise la variable définie précédemment pour nommer le groupe
# --location $Loc : Définit la région géographique (ex: norwayeast) pour la métadonnée du groupe
Write-Host "--- Étape 2 : Création des VNets et Subnets ---" -ForegroundColor Cyan
# --- CRÉATION DES RÉSEAUX VIRTUELS (VNETS) ---
# Le Hub centralise les services de sécurité et de gestion
az network vnet create -g $RG -n "VnetHub" --address-prefix "10.0.0.0/16" --location $Loc
# Spoke 1 : Réseau isolé pour le premier segment applicatif (ex: Projet A)
az network vnet create -g $RG -n "VnetSpoke1" --address-prefix "192.168.0.0/24" --location $Loc
# Spoke 2 : Réseau isolé pour le second segment applicatif (ex: Projet B)
az network vnet create -g $RG -n "VnetSpoke2" --address-prefix "172.16.0.0/24" --location $Loc
# --- SOUS-RÉSEAUX DU HUB (SERVICES PARTAGÉS) ---
# IMPORTANT : 'AzureFirewallSubnet' est un nom réservé requis pour le déploiement du pare-feu
az network vnet subnet create -g $RG --vnet-name "VnetHub" -n "AzureFirewallSubnet" --address-prefix "10.0.2.0/24"
# IMPORTANT : 'AzureBastionSubnet' est requis pour le service d'accès sécurisé Bastion
az network vnet subnet create -g $RG --vnet-name "VnetHub" -n "AzureBastionSubnet" --address-prefix "10.0.4.0/24"
# Sous-réseau 'Prod' du Hub pour les ressources communes (Contrôleurs de domaine, serveurs de logs, etc.)
az network vnet subnet create -g $RG --vnet-name "VnetHub" -n "Prod" --address-prefix "10.0.1.0/24"
# --- SOUS-RÉSEAUX DES SPOKES (WORKLOADS) ---
# Sous-réseau de production pour le Spoke 1 (Hébergement des VMs applicatives)
az network vnet subnet create -g $RG --vnet-name "VnetSpoke1" -n "Prod" --address-prefix "192.168.0.0/24"
# Sous-réseau de production pour le Spoke 2 (Hébergement des VMs applicatives)
az network vnet subnet create -g $RG --vnet-name "VnetSpoke2" -n "Prod" --address-prefix "172.16.0.0/24"
Write-Host "--- Étape 3 : Configuration de la Sécurité Réseau (NSG) ---" -ForegroundColor Cyan
# --- 1. CRÉATION DES GROUPES DE SÉCURITÉ ---
# Ces groupes agissent comme des pare-feu de couche 4 (L4) au niveau du subnet.
az network nsg create -g $RG -n "NSG-Spoke1" --location $Loc
az network nsg create -g $RG -n "NSG-Spoke2" --location $Loc
# --- 2. AJOUT DES RÈGLES D'AUTORISATION (ICMP/PING) ---
# Par défaut, Azure bloque le trafic venant d'autres VNets.
# Ces règles permettent explicitement au protocole ICMP de circuler.
Write-Host "Ajout des règles d'autorisation Ping..." -ForegroundColor Gray
# Règle pour le Spoke 1
az network nsg rule create -g $RG --nsg-name "NSG-Spoke1" -n "Allow-Ping-Inbound" `
--priority 100 --access Allow --protocol Icmp --direction Inbound `
--source-address-prefixes "*" --destination-address-prefixes "*" --source-port-ranges "*" --destination-port-ranges "*"
# Règle pour le Spoke 2
az network nsg rule create -g $RG --nsg-name "NSG-Spoke2" -n "Allow-Ping-Inbound" `
--priority 100 --access Allow --protocol Icmp --direction Inbound `
--source-address-prefixes "*" --destination-address-prefixes "*" --source-port-ranges "*" --destination-port-ranges "*"
# --- 3. ASSOCIATION AUX SOUS-RÉSEAUX ---
# Applique les règles de sécurité aux sous-réseaux 'Prod' respectifs.
Write-Host "Liaison des NSG aux sous-réseaux..." -ForegroundColor Gray
az network vnet subnet update -g $RG --vnet-name "VnetSpoke1" -n "Prod" --network-security-group "NSG-Spoke1"
az network vnet subnet update -g $RG --vnet-name "VnetSpoke2" -n "Prod" --network-security-group "NSG-Spoke2"
Write-Host "--- Étape 4 : Création des VMs ---" -ForegroundColor Cyan
# --- CRÉATION DE LA VM DANS LE SPOKE 1 ---
# az vm create : Commande principale pour générer la machine virtuelle
# --image : Utilise la dernière version de Windows Server 2022 (Génération 2 pour de meilleures performances)
# --size : Type 'Standard_B2s' (Économique, idéal pour les environnements de test/burstable)
# --admin-username/password : Utilise les variables globales de sécurité définies au début
# --public-ip-address "" : TRÈS IMPORTANT : On n'attribue AUCUNE IP publique pour garantir la sécurité
# --nsg : Attache la VM au groupe de sécurité créé à l'étape précédente
az vm create -g $RG -n "VM-SPOKE-1" --image "MicrosoftWindowsServer:WindowsServer:2022-Datacenter-g2:latest" `
--size "Standard_B2s" --admin-username $AdminUser --admin-password $AdminPass `
--vnet-name "VnetSpoke1" --subnet "Prod" --public-ip-address "" --nsg "NSG-Spoke1"
# --- CRÉATION DE LA VM DANS LE SPOKE 2 ---
# Processus identique pour le second segment réseau
az vm create -g $RG -n "VM-SPOKE-2" --image "MicrosoftWindowsServer:WindowsServer:2022-Datacenter-g2:latest" `
--size "Standard_B2s" --admin-username $AdminUser --admin-password $AdminPass `
--vnet-name "VnetSpoke2" --subnet "Prod" --public-ip-address "" --nsg "NSG-Spoke2"
Write-Host "--- Étape 5 : Déploiement du Firewall (Attente estimée : 10-15 min) ---" -ForegroundColor Yellow
# --- CRÉATION DE L'IP PUBLIQUE POUR LE FIREWALL ---
# Le Firewall nécessite une IP publique de SKU 'Standard' pour sortir sur Internet
# Cette IP servira de point de sortie unique pour tous les flux des Spokes
az network public-ip create -g $RG -n "IP-Firewall" --sku Standard --location $Loc
# --- CRÉATION DE L'INSTANCE FIREWALL ---
# --sku "AZFW_VNet" : Spécifie que le firewall est déployé directement dans un réseau virtuel
# --tier "Standard" : Offre un filtrage de niveau L3-L7 et l'inspection FQDN
az network firewall create -g $RG -n "AzureFireWall" --location $Loc --sku "AZFW_VNet" --tier "Standard"
# --- CONFIGURATION IP DU FIREWALL ---
# Cette commande lie l'instance Firewall à son sous-réseau dédié (AzureFirewallSubnet)
# et lui attribue son adresse IP publique créée précédemment
az network firewall ip-config create -g $RG -f "AzureFireWall" -n "FW-Config" `
--public-ip-address "IP-Firewall" --vnet-name "VnetHub"
Write-Host "--- Étape 6 : Création des Tables de Routage ---" -ForegroundColor Magenta
# --- CRÉATION DE LA TABLE POUR LE SPOKE 1 ---
# Une table de routage contient un ensemble de règles (itinéraires) qui définissent
# où les paquets de données doivent être envoyés.
az network route-table create -g $RG -n "UdrSpoke1" --location $Loc
# --- CRÉATION DE LA TABLE POUR LE SPOKE 2 ---
# On crée une table distincte par Spoke pour permettre une gestion granulaire
# des flux sortants de chaque réseau.
az network route-table create -g $RG -n "UdrSpoke2" --location $Loc
Write-Host "--- Étape 7 : Établissement des Peerings (Interconnexion VNet) ---" -ForegroundColor Magenta
# =============================================================================
# NOTE : Pour qu'un Peering soit fonctionnel, il doit être créé dans les DEUX SENS.
# L'option --allow-forwarded-traffic est indispensable pour que l'Azure Firewall
# puisse router les paquets entre les Spokes.
# =============================================================================
# --- LIAISON : HUB <--> SPOKE 1 ---
Write-Host "Liaison Hub <-> Spoke 1..." -ForegroundColor Gray
# 1. Aller : Du Hub vers le Spoke 1
az network vnet peering create -g $RG --name "HubToSpoke1" `
--vnet-name "VnetHub" --remote-vnet "VnetSpoke1" `
--allow-vnet-access --allow-forwarded-traffic
# 2. Retour : Du Spoke 1 vers le Hub
az network vnet peering create -g $RG --name "Spoke1ToHub" `
--vnet-name "VnetSpoke1" --remote-vnet "VnetHub" `
--allow-vnet-access --allow-forwarded-traffic
# --- LIAISON : HUB <--> SPOKE 2 ---
Write-Host "Liaison Hub <-> Spoke 2..." -ForegroundColor Gray
# 1. Aller : Du Hub vers le Spoke 2
az network vnet peering create -g $RG --name "HubToSpoke2" `
--vnet-name "VnetHub" --remote-vnet "VnetSpoke2" `
--allow-vnet-access --allow-forwarded-traffic
# 2. Retour : Du Spoke 2 vers le Hub (CRITIQUE : Était manquant !)
az network vnet peering create -g $RG --name "Spoke2ToHub" `
--vnet-name "VnetSpoke2" --remote-vnet "VnetHub" `
--allow-vnet-access --allow-forwarded-traffic
Write-Host "--- Étape 8 : Configuration du Next Hop via Firewall ---" -ForegroundColor Magenta
# Option A : Demander à l'utilisateur de saisir l'IP
$FW_IP = Read-Host "Veuillez entrer l'IP privée de l'Azure Firewall (ex: 10.0.2.4)"
# Validation rapide pour s'assurer que l'IP n'est pas vide
if (-not $FW_IP) {
Write-Host "Erreur : L'adresse IP est obligatoire." -ForegroundColor Red
return
}
# Création des routes avec l'IP saisie
az network route-table route create -g $RG --route-table-name "UdrSpoke1" -n "To-Spoke2" `
--address-prefix "172.16.0.0/24" --next-hop-type VirtualAppliance --next-hop-ip-address $FW_IP
az network route-table route create -g $RG --route-table-name "UdrSpoke2" -n "To-Spoke1" `
--address-prefix "192.168.0.0/24" --next-hop-type VirtualAppliance --next-hop-ip-address $FW_IP
# Association des tables de routage aux subnets
az network vnet subnet update -g $RG --vnet-name "VnetSpoke1" -n "Prod" --route-table "UdrSpoke1"
az network vnet subnet update -g $RG --vnet-name "VnetSpoke2" -n "Prod" --route-table "UdrSpoke2"
Write-Host "--- Étape 9 : Configuration des règles Network (Ping Inter-Spoke) ---" -ForegroundColor Yellow
# --- RÈGLE 1 : FLUX SORTANT DU SPOKE 1 VERS LE SPOKE 2 ---
# --collection-name : Regroupe les règles logiquement. La priorité (100) définit l'ordre d'évaluation.
# --action Allow : Autorise explicitement le passage des paquets.
# --protocols ICMP : Autorise le protocole utilisé par la commande 'Ping'.
# --destination-ports "*" : Pour l'ICMP, le port n'est pas utilisé, on met donc une étoile.
az network firewall network-rule create -g $RG -f "AzureFireWall" `
--collection-name "Allow-InterSpoke" --priority 100 --action Allow `
--name "Spoke1-to-Spoke2-Ping" --protocols ICMP `
--source-addresses "192.168.0.0/24" `
--destination-addresses "172.16.0.0/24" --destination-ports "*"
# --- RÈGLE 2 : FLUX RETOUR OU SORTANT DU SPOKE 2 VERS LE SPOKE 1 ---
# On utilise la même collection "Allow-InterSpoke" pour une gestion centralisée.
# Cette règle permet à la VM du Spoke 2 de répondre ou d'initier un ping vers le Spoke 1.
az network firewall network-rule create -g $RG -f "AzureFireWall" `
--collection-name "Allow-InterSpoke" `
--name "Spoke2-to-Spoke1-Ping" --protocols ICMP `
--source-addresses "172.16.0.0/24" `
--destination-addresses "192.168.0.0/24" --destination-ports "*"
Write-Host "--- Étape 10 : Déploiement d'Azure Bastion ---" -ForegroundColor Cyan
# --- CRÉATION DE L'IP PUBLIQUE POUR BASTION ---
# Comme le Firewall, Bastion a besoin d'une IP publique 'Standard' pour être joignable.
# Cependant, cette IP ne sert qu'à établir un tunnel SSL (port 443) vers votre navigateur.
az network public-ip create -g $RG -n "IP-Bastion" --sku Standard --location $Loc
# --- CRÉATION DU SERVICE BASTION ---
# Cette commande déploie l'instance Bastion dans le sous-réseau 'AzureBastionSubnet'.
# Bastion permet de se connecter en RDP/SSH à vos VMs directement depuis le portail Azure.
# Avantage : Vos VMs n'ont pas besoin d'IP publique et le port 3389 n'est pas ouvert sur le web.
az network bastion create -g $RG -n "AzureBastion" --public-ip-address "IP-Bastion" `
--vnet-name "VnetHub" --location $Loc
foreach ($group in $groups) {
$categoryName = ($group.Name.Split('/')[-1]).ToUpper()
$count = $group.Count
Write-Host "`n┌──────────────────────────────────────────────────────────┐" -ForegroundColor Cyan
Write-Host " [#] CATEGORY : $categoryName ($count)" -ForegroundColor Cyan
Write-Host "└──────────────────────────────────────────────────────────┘" -ForegroundColor Cyan
$group.Group | ForEach-Object {
$statusSymbol = if ($_.Status -eq "Succeeded") { "✔" } else { "✘" }
[PSCustomObject]@{
" STATUT" = "$statusSymbol $($_.Status)"
" NOM DE LA RESSOURCE" = $_.Name
" TYPE AZURE" = ($_.FullType.Split('/')[-1])
}
} | Format-Table -AutoSize | Out-String | Write-Host -ForegroundColor White
}
Cette étape permet d’accéder de manière sécurisée aux machines virtuelles sans exposer d’adresses IP publiques. Azure Bastion fournit un accès RDP/SSH directement depuis le portail Azure, en utilisant une connexion chiffrée via le navigateur. Grâce à cette configuration, les VMs restent isolées du réseau public tout en restant accessibles pour l’administration, le dépannage et les tests. Cette approche renforce la sécurité globale de l’architecture Hub & Spoke.
Afin de permettre les tests de connectivité entre les machines virtuelles, il est nécessaire d’activer la découverte réseau et d’autoriser le protocole ICMP (Ping) sur chaque VM.
- Ouvrir l’Explorateur de fichiers.
- Cliquer sur Réseau dans le menu de gauche.
- Si un message d’alerte s’affiche en haut de la fenêtre, cliquer sur Activer la découverte réseau et le partage de fichiers.
- Confirmer l’activation pour le réseau privé.
- Vérifier que le pare-feu Windows autorise les règles ICMP (Ping) entrantes.
Cette configuration permet aux deux machines virtuelles de se détecter mutuellement sur le réseau et d’effectuer des tests de connectivité (Ping) dans le cadre de l’architecture Hub & Spoke.
Exécutez cette commande pour supprimer tous les composants créés ci-dessus d'un seul coup et arrêter la facturation.
Write-Host "`n"
Write-Host "==========================================================" -ForegroundColor Red
Write-Host "PROCÉDURE DE NETTOYAGE : SUPPRESSION DE L'INFRASTRUCTURE" -ForegroundColor Red
Write-Host "==========================================================" -ForegroundColor Red
Write-Host "Groupe de ressources : $RG" -ForegroundColor White
Write-Host "Statut : Suppression en cours, veuillez patienter..." -ForegroundColor Yellow
# Suppression synchronisée (le script attend la fin réelle)
az group delete --name $RG --yes
# Message de succès final
Write-Host "`n"
Write-Host "----------------------------------------------------------" -ForegroundColor Green
Write-Host "SUCCÈS : L'infrastructure a été supprimée avec succès." -ForegroundColor Green
Write-Host "Toutes les ressources liées à $RG ont été nettoyées." -ForegroundColor Green
Write-Host "----------------------------------------------------------" -ForegroundColor Green







