Cloud
Azure App Service : diagnostiquer les échecs Health Check avant de redémarrer les instances
Un runbook de production pour séparer endpoint de santé défectueux, instance dégradée, redirection, authentification et panne de dépendance avant de redémarrer ou modifier Health Check.
Un Azure App Service reste joignable alors que Health Check déclare une ou plusieurs instances unhealthy. Le trafic se concentre sur les workers restants, la latence augmente, ou la plateforme sort régulièrement la même instance de la rotation. Redémarrer l’application peut effacer le symptôme, mais aussi l’état du processus et la chronologie nécessaires pour distinguer un worker défaillant d’un mauvais contrat de santé.
Le cas fil rouge est une API de production répartie sur plusieurs instances App Service. Health Check appelle /health/ready, qui vérifie la base de données et une dépendance de messaging. Après une release, quelques instances échouent, puis toute l’application renvoie par intermittence des réponses hors 2xx. Ce runbook doit produire une décision : corriger l’endpoint, isoler une instance, rollbacker l’application ou restaurer la configuration Health Check précédente sans masquer la panne d’une dépendance partagée.
Figer le contrat de santé et la fenêtre d’incident
Health Check pilote le trafic ; ce n’est pas seulement une URL de monitoring. Avant de modifier le chemin ou le seuil d’échec, documentez ce que promet l’endpoint.
incident: inc-20260910-006
app: app-orders-prod
slot: production
plan: asp-orders-prod
region: westeurope
instances_attendues: 4
health_path: /health/ready
premiere_instance_unhealthy_utc: 2026-09-10T14:12:00Z
release: orders-api-2026.09.10.3
contrat_sante:
statut_healthy: 200-299
anonyme_ou_authentifie_par_plateforme: explicite
controles:
- processus_ready
- lecture_base_de_donnees
- connexion_service_bus
exclusions:
- api_reporting_non_critique
- ecriture_metier
a_preserver_avant_action:
- configuration_health_check
- metrique_par_instance
- logs_applicatifs_et_dependances
- chronologie_deploiements_et_configuration
- memoire_threads_et_redemarrages_processus
- revision_precedente_et_commande_rollback Ne commencez pas par augmenter le seuil d’échec. Un seuil supérieur retarde l’exclusion ; il ne rend pas l’endpoint plus représentatif. Notez aussi si le site utilise une ou plusieurs instances. Avec une seule instance, Health Check peut signaler la panne mais ne peut pas rerouter le trafic vers un autre worker sain.
Lire la configuration réellement déployée
Capturez la configuration du site et les deux paramètres qui contrôlent l’exclusion des workers. App Service appelle le chemin configuré sur chaque instance à une minute d’intervalle. Une réponse hors 200-299, un timeout, une demande d’authentification ou une redirection peuvent créer un écart entre la vue plateforme et un test manuel.
set -eu
RG="rg-app-prod"
APP="app-orders-prod"
az webapp config show \
--resource-group "$RG" \
--name "$APP" \
--query '{healthCheckPath:healthCheckPath,alwaysOn:alwaysOn,http20Enabled:http20Enabled,ftpsState:ftpsState}' \
--output json
az webapp config appsettings list \
--resource-group "$RG" \
--name "$APP" \
--query "[?name=='WEBSITE_HEALTHCHECK_MAXPINGFAILURES' || name=='WEBSITE_HEALTHCHECK_MAXUNHEALTHYWORKERPERCENT'].{name:name,value:value}" \
--output table Conservez aussi le comportement des slots dans la capture. La configuration Health Check est échangée pendant un slot swap ; production et staging doivent donc employer des chemins et une sémantique compatibles. Sinon, le swap peut promouvoir un bon code avec un contrat de probe invalide à destination.
Séparer échec de probe et panne d’instance
Testez l’endpoint par le chemin public ou privé réel, puis corrélez le résultat avec les preuves par instance. Une requête cliente réussie prouve seulement qu’un worker sain a répondu. Un échec global pointe vers l’endpoint ou une dépendance commune ; l’échec d’une seule instance oriente davantage vers le processus local, le filesystem, la mémoire ou l’état du worker.
Une instance unhealthy
Comparer dimension Instance, redemarrages, memoire, threads et logs locaux
Verifier que release et warm-up ont termine sur ce worker
Preserver les diagnostics avant redemarrage ou remplacement
Toutes les instances unhealthy ensemble
Verifier code de l’endpoint, dependance partagee, DNS, identite et configuration
Ne pas choisir le remplacement des workers comme premiere correction
La plateforme evite de retirer toutes les instances simultanement
Le test manuel retourne 200, Health Check echoue
Verifier comportement du hostname par defaut, redirections et authentification
Confirmer que le test manuel utilise exactement le chemin configure
Comparer HTTPS Only et les redirections applicatives
L’endpoint est vert alors que les utilisateurs echouent
La probe est trop superficielle ou contourne la dependance en panne
Ajouter une lecture representative sans transformer health en transaction
Separer clairement liveness et readiness L’endpoint doit rester peu coûteux et déterministe. Il doit prouver que l’instance peut servir la classe de requêtes représentée par l’application, sans créer de données, consommer de messages ni échouer à cause d’un service analytique optionnel.
Vérifier explicitement redirections et authentification
App Service Health Check attend un statut 200-299 et ne suit pas les redirections. Une redirection du hostname par défaut vers un domaine personnalisé, une redirection HTTPS applicative ou un challenge de connexion peuvent déclarer tous les workers en échec alors qu’un navigateur finit par afficher une page verte.
set -eu
DEFAULT_HOST="app-orders-prod.azurewebsites.net"
CUSTOM_HOST="orders.example.com"
PATH_TO_TEST="/health/ready"
curl --silent --show-error --output /dev/null \
--write-out 'default status=%{http_code} redirect=%{redirect_url} time=%{time_total}\n' \
"https://$DEFAULT_HOST$PATH_TO_TEST"
curl --silent --show-error --output /dev/null \
--write-out 'custom status=%{http_code} redirect=%{redirect_url} time=%{time_total}\n' \
"https://$CUSTOM_HOST$PATH_TO_TEST" Si App Service Authentication protège l’application, vérifiez son intégration supportée avec Health Check. Si l’application porte son propre mécanisme d’authentification, le chemin doit autoriser la requête plateforme ou valider le token interne documenté. Ne résolvez pas l’incident en exposant un endpoint de diagnostic bavard qui révèle les dépendances, des secrets ou la topologie.
Corréler santé, runtime et dépendances
Lisez HealthCheckStatus avec la dimension Instance, puis comparez la même fenêtre avec requêtes, exceptions, dépendances en échec, mémoire et redémarrages. Le statut Health Check n’apparaît qu’après atteinte du seuil d’échecs configuré ; conservez donc les événements applicatifs antérieurs.
let StartTime = datetime(2026-09-10T14:00:00Z);
let EndTime = datetime(2026-09-10T15:00:00Z);
let AppResource = "app-orders-prod";
AzureMetrics
| where TimeGenerated between (StartTime .. EndTime)
| where Resource =~ AppResource
| where MetricName in ("HealthCheckStatus", "Http5xx", "MemoryWorkingSet", "Requests")
| extend Instance = tostring(column_ifexists("Instance", "not-exported"))
| summarize Average=avg(Average), Maximum=max(Maximum), Total=sum(Total) by bin(TimeGenerated, 5m), MetricName, Instance
| order by TimeGenerated asc, Instance asc La forme des tables et dimensions peut varier selon le chemin de diagnostic retenu. Conservez l’export brut des métriques si la projection Log Analytics ne porte pas la dimension d’instance. Corrélez ensuite la télémétrie applicative : durée de l’endpoint, dépendance en erreur, révision, role instance et type d’exception.
Décider si une dépendance appartient à la readiness
Un endpoint de santé peut provoquer une panne auto-infligée s’il échoue sur une dépendance dégradée mais non critique. Il peut aussi rester vert alors que l’application a perdu la base nécessaire à toutes les requêtes. Classez chaque contrôle selon son impact utilisateur et son mode de récupération.
dependances:
base_principale:
critique: true
probe: lecture_bornee
timeout_ms: 500
unhealthy_on: echecs_repetes
service_bus:
critique_pour: commandes_en_ecriture
probe: connexion_ou_lecture_management
timeout_ms: 500
mode_degrade: lectures_ok_nouvelles_commandes_refusees
api_reporting:
critique: false
probe: telemetrie_uniquement
unhealthy_on: jamais_seule
regles_endpoint:
- aucune_ecriture_metier
- aucun_secret_ou_topologie_dans_reponse
- budget_total_inferieur_au_timeout_plateforme
- cache_uniquement_si_staleness_visible
- raison_dependance_et_instance_dans_logs_internes Quand la dépendance partagée est la cause, retirer des workers ne fait que concentrer le trafic sur les instances restantes. Préférez un mode dégradé borné, un circuit breaker ou la restauration de la dépendance lorsque le contrat métier le permet. Ne modifiez la sémantique de la probe que si le contrat actuel est manifestement incorrect.
Choisir une correction avec chemin de retour
Évitez d’empiler redémarrage, modification du seuil et réécriture de l’endpoint dans le même incident. Choisissez l’action minimale qui teste l’hypothèse prouvée.
Corriger l’endpoint
Redirection, authentification ou mauvais statut explique l’echec plateforme
Politique de dependance trop large ou budget de timeout invalide
Valider sur un slot avant d’appliquer en production
Isoler ou redemarrer une instance
Echec lie a un worker et diagnostics preserves
Capacite mesuree suffisante sur les autres instances
Validation post-redemarrage capable d’identifier instance et revision
Rollbacker l’application
Echec commence avec une release et suit la nouvelle revision
Endpoint et erreurs metier regressent ensemble
Revision et configuration precedentes connues saines
Restaurer la configuration Health Check precedente
Chemin ou seuil modifie independamment de la release
Ancien chemin toujours representatif et securise
Rollback ne masque pas une panne applicative reelle
Bloquer toute nouvelle action
Tous les workers echouent sur une dependance partagee
Capacite restante inconnue
Logs incapables de separer probe et panne applicative Une modification de configuration Health Check redémarre l’application. Traitez donc son rollback comme une action de production : utilisez un slot de staging si possible, capturez les paramètres avant et après, et ne changez pas le chemin uniquement pour faire taire la métrique.
Valider sur plusieurs cycles de probe
Un unique 200 ne prouve pas la récupération. Maintenez le candidat sur plusieurs cycles d’une minute et sous trafic normal. Vérifiez que toutes les instances attendues sont saines, que le trafic est distribué, que les erreurs de dépendance restent bornées et que l’endpoint détecte toujours un cas négatif volontaire dans un environnement sûr.
Conserver la correction
HealthCheckStatus stable sur chaque instance attendue
Taux d’erreur utilisateur et latence revenus a la baseline
Endpoint dans son budget de reponse
Aucun loop de redemarrage ou d’exclusion
Echec d’une dependance critique rend toujours readiness negative
Echec d’une dependance optionnelle ne retire plus de capacite saine
Rollbacker ou maintenir le blocage
Seule la requete synthetique est verte
Metrique amelioree mais erreurs utilisateur persistantes
Une instance sort regulierement de la rotation
Workers restants proches de leurs limites
Endpoint expose des details sensibles
Contrat de probe different entre production et staging Conclusion
App Service Health Check n’est utile que si son endpoint représente la décision de trafic que la plateforme doit prendre. Quand des workers passent unhealthy, figez le contrat, lisez la configuration déployée, séparez panne locale et dépendance partagée, puis vérifiez redirections et authentification avant tout redémarrage.
La décision finale doit rester étroite et observable : corriger l’endpoint, isoler un worker prouvé défaillant, restaurer la configuration précédente, rollbacker la release ou maintenir un mode dégradé contrôlé pendant la récupération de la dépendance. Le service n’est rétabli que lorsque la métrique plateforme et le chemin utilisateur convergent sur plusieurs cycles de probe.