Networking
Azure App Service VNet Integration : diagnostiquer l’épuisement du subnet avant de relancer le scaling
Un runbook de production pour mesurer la capacité d’un subnet VNet Integration, distinguer manque d’adresses, délégation et panne réseau, puis valider un redimensionnement ou une migration avec rollback.
Un plan Azure App Service reste joignable, mais un scale-out ou un scale-up n’aboutit pas. Les métriques applicatives montrent toujours de la charge, les instances existantes répondent et aucune règle NSG n’a changé. Le réflexe est souvent de relancer l’opération, d’augmenter encore la capacité cible ou de chercher une panne dans l’application. Pourtant, le blocage peut se trouver dans le subnet de VNet Integration : il n’offre plus assez d’adresses pour créer la nouvelle cohorte de workers.
Le cas fil rouge est un plan de production à huit instances intégré à un ancien subnet /28. Onze adresses y sont utilisables après les cinq adresses réservées par Azure. Une opération de changement de taille peut devoir maintenir les huit anciennes instances pendant que huit nouvelles démarrent. Le besoin transitoire atteint alors seize adresses, avant même de compter un autre plan ou le cas particulier des Windows Containers. Le runbook doit décider entre quatre actions : libérer une pression temporaire, réduire la cible de scaling, migrer vers un subnet dimensionné, ou rollbacker le changement qui a déclenché l’opération.
Figer le contrat de capacité
Ne commencez pas par détacher l’intégration réseau. Cette action redémarre l’application et détruit une partie de l’état utile au diagnostic. Capturez d’abord le plan, le subnet, l’opération et la capacité attendue.
Fenetre UTC: 2026-10-03 05:35Z a maintenant
Application / slot: api-orders-prod / production
App Service plan: asp-orders-prod
Instances actives avant incident: 8
Operation demandee: scale-up P1v3 vers P2v3
Subnet VNet Integration: snet-appsvc-integration-prod
Prefixe: 10.42.8.0/28
Symptome
Operation de scaling incomplete ou en echec
Instances existantes toujours joignables
Pas de changement DNS, UDR ou NSG confirme
Decision attendue
Attendre une liberation d'adresses prouvee
Revenir a la taille precedente
Migrer vers un subnet avec marge validee
Escalader un incident plateforme avec preuves Conservez l’ID de l’opération Azure, les événements Activity Log, l’heure de la dernière modification de l’intégration et la chronologie d’autoscale. Une relance sans ces éléments peut créer une nouvelle tentative qui brouille la cause initiale.
Prouver quel plan consomme quel subnet
VNet Integration est un chemin de sortie. Un Private Endpoint éventuellement présent protège un chemin d’entrée ou l’accès à une dépendance ; il ne fournit aucune capacité au subnet d’intégration. Inventoriez donc les applications et plans réellement reliés au subnet, sans déduire la consommation à partir des Private Endpoints voisins.
RG_APP="rg-orders-prod"
APP="api-orders-prod"
PLAN="asp-orders-prod"
az webapp vnet-integration list --resource-group "$RG_APP" --name "$APP" --output json
az appservice plan show --resource-group "$RG_APP" --name "$PLAN" --query '{id:id,sku:sku.name,capacity:sku.capacity,kind:kind,reserved:reserved}' --output json
az monitor autoscale list --resource-group "$RG_APP" --output json Pour repérer d’autres applications qui déclarent le même subnet, utilisez Azure Resource Graph. La requête donne un inventaire de configuration, pas un compteur d’adresses libres : regroupez ensuite les résultats par App Service plan et vérifiez chaque intégration.
let subnet = tolower('/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-net-prod/providers/Microsoft.Network/virtualNetworks/vnet-prod/subnets/snet-appsvc-integration-prod');
resources
| where type =~ 'microsoft.web/sites'
| extend integrationSubnet = tolower(tostring(properties.virtualNetworkSubnetId))
| where integrationSubnet == subnet
| project subscriptionId, resourceGroup, app=name,
appServicePlan=tostring(properties.serverFarmId), integrationSubnet Complétez l’inventaire par les slots, les intégrations configurées via les propriétés réseau du site et les plans joints au même subnet. Avec Multi Plan Subnet Join, la marge est commune : additionnez les instances de tous les plans, pas seulement celles de l’application en incident.
Calculer l’enveloppe, y compris le pic transitoire
Azure réserve cinq adresses dans chaque subnet. Pour App Service multitenant, une instance de plan consomme normalement une adresse dans chaque subnet d’intégration utilisé. Lors d’un scale-up ou d’un scale-down en taille, les anciennes et nouvelles instances peuvent coexister : la consommation du plan est alors temporairement doublée. Une mise à niveau de plateforme a elle aussi besoin de marge. Les adresses libérées après une opération peuvent rester occupées pendant un délai court et, dans de rares cas, jusqu’à douze heures.
Écrivez le calcul au lieu de conclure à partir du seul CIDR.
Subnet /28
Adresses totales 16
Adresses reservees par Azure 5
Adresses utilisables 11
Plan asp-orders-prod
Instances actuelles 8
Nouvelle cohorte pendant scale-up 8
Pic transitoire du plan 16
Marge au pic: 11 - 16 = -5
Decision: le subnet ne peut pas porter cette operation de facon sure Pour un subnet partagé, calculez au minimum :
adresses nécessaires au pic = somme des instances stables des autres plans + 2 × instances du plan en opération + réserve d’exploitation.
Adaptez la formule si plusieurs plans scalent simultanément. Pour des Windows Containers, ajoutez l’adresse supplémentaire consommée par application et par instance de plan. Ne transformez pas la recommandation “deux fois le maximum prévu” en simple règle documentaire : utilisez-la pour couvrir le chevauchement de scaling et les opérations de plateforme. Pour un environnement de production, un /26 constitue le point de départ recommandé par Microsoft, mais le bon préfixe dépend toujours du nombre de plans, d’applications conteneurisées et d’intégrations.
Distinguer épuisement, délégation et panne de chemin
Un subnet presque plein n’explique pas tous les échecs. Vérifiez sa délégation, ses associations et son préfixe avant d’annoncer une saturation.
RG_NET="rg-net-prod"
VNET="vnet-prod"
SUBNET="snet-appsvc-integration-prod"
az network vnet subnet show --resource-group "$RG_NET" --vnet-name "$VNET" --name "$SUBNET" --query '{prefixes:addressPrefixes,delegations:delegations[].serviceName,nsg:networkSecurityGroup.id,routeTable:routeTable.id,serviceAssociationLinks:serviceAssociationLinks[].id}' --output json Séparez les branches du diagnostic :
- une création de worker échoue pendant que les instances présentes restent saines : capacité ou opération de plateforme probable ;
- aucune instance ne reçoit d’adresse privée : intégration, délégation ou Service Association Link à contrôler ;
- les instances ont une adresse mais une dépendance devient inaccessible : DNS, UDR, NSG, firewall ou retour réseau ;
- seule une application Windows Container échoue après ajout d’apps : recalculer le multiplicateur propre aux conteneurs ;
- le compteur semble suffisant juste après un scale-in : rechercher une libération différée avant toute nouvelle relance.
WEBSITE_PRIVATE_IP permet de confirmer qu’une instance a reçu une adresse du subnet. Cette valeur peut changer : ne l’ajoutez pas individuellement à une allowlist. Les destinations doivent autoriser le préfixe d’intégration prévu, sous réserve des contrôles de sécurité définis pour le flux.
Choisir une correction qui ne déplace pas l’incident
Si le déficit est transitoire et qu’aucune montée en charge n’est nécessaire, attendez la libération observée et bloquez les relances automatiques concurrentes. Si l’autoscale demande une cible supérieure à l’enveloppe, réduisez temporairement son maximum avec un ticket, une durée et un seuil de sortie. Ce confinement ne remplace pas un subnet correctement dimensionné.
Un subnet déjà affecté à VNet Integration ne se redimensionne pas sur place. La correction durable consiste généralement à préparer un nouveau subnet, dédié, délégué à Microsoft.Web/serverFarms, avec les NSG, UDR et dépendances DNS nécessaires. Validez également l’espace d’adressage amont : créer un /26 qui chevauche une route on-premises produit un second incident plus difficile à lire.
az network vnet subnet create --resource-group "rg-net-prod" --vnet-name "vnet-prod" --name "snet-appsvc-integration-prod-v2" --address-prefixes "10.42.9.0/26" --delegations "Microsoft.Web/serverFarms"
az network vnet subnet show --resource-group "rg-net-prod" --vnet-name "vnet-prod" --name "snet-appsvc-integration-prod-v2" --output json Ne recopiez pas mécaniquement toutes les règles du subnet historique. Reconstituez le contrat de sortie attendu : serveurs DNS, préfixes privés, appliance éventuelle, NAT Gateway, destinations autorisées et chemin de retour. Une règle devenue inutile ne doit pas survivre uniquement parce qu’elle existait sur v1.
Canaryer la migration et garder un rollback
Quand le plan dispose encore d’une seconde intégration possible, utilisez une application canari représentative sur le même plan pour qualifier le nouveau subnet. Sinon, utilisez un plan de validation équivalent et documentez la différence. Le canari doit tester plus que /health : résolution DNS depuis l’application, connexion TCP aux dépendances privées, identité managée, sortie Internet si Route All est actif, adresse vue par une dépendance externe et télémétrie.
PROMOUVOIR
Inventaire des plans et slots complet
Enveloppe au pic compatible avec le nouveau prefixe
Delegation Microsoft.Web/serverFarms validee
DNS, UDR, NSG, NAT et retour reseau testes depuis le canari
Identite et dependances applicatives validees
Autoscale canari termine avec marge positive
ARRETER
Une application ou un plan partage reste inconnu
Le canari utilise un chemin DNS ou route different de production
Le scale cree des erreurs 5xx, timeouts ou refus d'identite
La marge n'inclut pas le chevauchement des instances
ROLLBACK
Reconnecter l'application au subnet precedent pendant la fenetre
Revenir a la capacite et au maximum autoscale valides
Annuler UDR, NSG ou NAT ajoutes uniquement pour la migration
Confirmer sante, chemin sortant et absence de nouvelle tentative de scale La bascule de l’intégration redémarre l’application. Traitez-la comme un changement de production avec fenêtre, sondes synthétiques et critère d’arrêt. Gardez l’ancien subnet intact jusqu’à validation de la nouvelle cohorte et de la première opération de scaling. Un rollback réseau sans retour à la capacité précédente peut relancer exactement le même échec.
Conclusion
Un scaling App Service bloqué n’est pas nécessairement un problème de quota compute ou de code. Avec VNet Integration, le subnet fait partie de l’enveloppe de capacité du plan : il doit absorber les instances stables, le chevauchement d’un changement de taille, les opérations de plateforme et les autres plans qui le partagent.
La décision de production doit donc être mesurable. Relancez uniquement si une adresse a réellement été libérée et si le pic calculé tient. Sinon, réduisez temporairement la cible ou migrez vers un subnet dimensionné, testé depuis une application représentative. Le rollback reste symétrique : ancienne intégration, ancienne capacité, règles réseau précédentes et validation applicative avant de rendre l’autoscale à nouveau autonome.