Networking

Azure Traffic Manager : diagnostiquer un profil dégradé avant de forcer le failover

Un runbook de production pour séparer santé applicative, contrat de probe, état des endpoints, réponses DNS, TTL et capacité secondaire avant de forcer une bascule Traffic Manager.

08 sept. 2026 azuretraffic-managerdnsfailoverhealth-probeobservabilitykqlroutingresiliencerunbookrollbackproduction

Un profil Azure Traffic Manager passe à l’état Degraded pendant que l’endpoint primaire répond encore aux tests de l’équipe. Une partie des utilisateurs atteint la région secondaire, d’autres conservent l’ancienne destination, et la pression monte pour désactiver manuellement le primaire. Ce geste peut accélérer la panne si la probe teste un mauvais chemin, si les caches DNS n’ont pas expiré ou si la région secondaire n’est pas prête à absorber la charge.

Ce runbook sert à décider avec des preuves : corriger la probe ou le backend, laisser le failover automatique agir, forcer une bascule bornée, ou restaurer la configuration précédente. Traffic Manager distribue des réponses DNS ; il ne déplace pas les connexions déjà établies et ne garantit pas que chaque résolveur respecte instantanément un changement.

Figer le contrat de bascule

Commencez par écrire le comportement attendu. Un statut dégradé n’indique pas à lui seul quel endpoint reçoit du trafic, pourquoi une probe échoue ni combien de clients utilisent encore une réponse en cache.

yaml traffic-manager-incident.yml
profile: tm-orders-prod
resource_group: rg-global-routing-prod
routing_method: Priority
public_name: api.example.com
traffic_manager_name: orders-prod.trafficmanager.net
incident_window: 2026-09-08T15:10:00Z/2026-09-08T15:40:00Z

endpoints:
primary: app-orders-weu.example.net
secondary: app-orders-neu.example.net

probe_contract:
protocol: HTTPS
port: 443
path: /health/ready
expected_status: 200-299
host_header: api.example.com

decision:
failover_only_if: primary-unhealthy-and-secondary-capacity-proven
rollback_on: secondary-errors-or-dns-answer-mismatch

Conservez le commit IaC, le dernier changement de probe, les priorités, le TTL et la fenêtre exacte. Identifiez aussi l’équipe qui valide la capacité applicative secondaire : un endpoint Online prouve une réponse de santé, pas un budget de charge.

Lire le profil et les endpoints réellement déployés

Séparez l’état administratif de l’état de monitoring. Un endpoint peut être Enabled mais Degraded; AlwaysServe peut aussi l’inclure dans le routage sans contrôle de santé. Lisez Azure avant de modifier le portail.

bash 01-read-traffic-manager-state.sh
RG="rg-global-routing-prod"
PROFILE="tm-orders-prod"

az network traffic-manager profile show \
--resource-group "$RG" \
--name "$PROFILE" \
--query '{status:profileStatus,monitor:monitorConfig,dns:dnsConfig,method:trafficRoutingMethod}' \
--output jsonc

az network traffic-manager endpoint list \
--resource-group "$RG" \
--profile-name "$PROFILE" \
--query '[].{name:name,type:type,status:endpointStatus,monitor:endpointMonitorStatus,target:target,priority:priority,weight:weight,alwaysServe:alwaysServe}' \
--output table

Vérifiez le type d’endpoint, la cible, la priorité ou le poids et les profils imbriqués éventuels. Une bascule forcée sur un profil parent ne corrige pas un seuil minChildEndpoints incohérent dans un profil enfant.

Rejouer exactement la probe

Une probe de santé n’est pas une requête utilisateur complète. Elle utilise le protocole, le port, le chemin, les plages de statuts et les en-têtes configurés. Un redirect, un certificat incompatible, un host header absent, une authentification ou une dépendance lente peut faire tomber la probe alors que la page d’accueil répond depuis un poste d’administration.

bash 02-replay-health-probe.sh
PRIMARY="app-orders-weu.example.net"
SECONDARY="app-orders-neu.example.net"
HOST="api.example.com"
PATH_READY="/health/ready"

for target in "$PRIMARY" "$SECONDARY"; do
curl --silent --show-error --output /dev/null \
  --write-out "$target status=%{http_code} connect=%{time_connect}s total=%{time_total}s\n" \
  --header "Host: $HOST" \
  --max-time 10 \
  "https://$target$PATH_READY"
done

Rejouez depuis plusieurs réseaux externes autorisés. N’utilisez pas -k comme preuve de santé : contourner la validation TLS masque précisément une cause possible. Si la cible attend SNI et un nom public, utilisez une résolution contrôlée avec curl --resolve plutôt qu’une requête vers l’IP.

La probe doit tester une readiness utile mais bornée. Une vérification qui traverse toutes les dépendances peut retirer une région pour une panne non critique. Une probe qui répond toujours 200 peut, à l’inverse, maintenir un endpoint incapable de servir les requêtes réelles.

Lire les événements de probe avant le statut courant

Le statut instantané ne donne pas la chronologie. Les resource logs ProbeHealthStatusEvents permettent d’identifier l’endpoint, les transitions et la description du résultat. Corrélez-les avec les logs du backend sur la même fenêtre UTC.

kusto 03-traffic-manager-probe-events.kql
let Start = datetime(2026-09-08T15:00:00Z);
let End = datetime(2026-09-08T15:50:00Z);
AzureDiagnostics
| where TimeGenerated between (Start .. End)
| where ResourceType == "TRAFFICMANAGERPROFILES"
| where Category == "ProbeHealthStatusEvents"
| project TimeGenerated,
        EndpointName = EndpointName_s,
        ProbeStatus = Status_s,
        ResultDescription,
        ResourceId = _ResourceId
| order by TimeGenerated asc

Une transition isolée suivie d’un retour rapide peut être transitoire. Des échecs persistants alignés avec des 5xx, timeouts TLS ou saturations backend justifient une action sur la région. L’absence de logs impose d’abord de vérifier les diagnostic settings ; elle ne prouve pas que les probes n’ont pas échoué.

Prouver la réponse DNS vue par les clients

Traffic Manager agit au niveau DNS. Interrogez plusieurs résolveurs et conservez la chaîne CNAME, la réponse finale et le TTL. Une résolution locale répétée peut seulement relire le cache de l’entreprise.

bash 04-dns-answer-matrix.sh
NAME="api.example.com"

for resolver in 1.1.1.1 8.8.8.8; do
echo "resolver=$resolver"
dig +noall +answer @$resolver "$NAME" CNAME
dig +noall +answer @$resolver "$NAME" A
done

# Interroger aussi le résolveur d'entreprise depuis un réseau utilisateur réel.
dig +noall +answer "$NAME" CNAME
dig +noall +answer "$NAME" A

Un changement d’état ne coupe pas les connexions existantes. Les résolveurs et clients peuvent conserver une ancienne réponse jusqu’à expiration du TTL, parfois davantage selon leur comportement. Mesurez donc le temps de convergence depuis plusieurs points au lieu d’annoncer une bascule terminée dès que le portail change.

Vérifier que la région secondaire peut réellement prendre la charge

Avant de désactiver le primaire, validez la région secondaire comme une cible de production, pas comme une simple URL de santé.

text secondary-readiness-gate.txt
Capacite secondaire
Instances, quotas et autoscaling suffisants
Dependances regionales disponibles
Pool de connexions et limites aval connus

Contrat applicatif
Meme version ou version compatible
Configuration et feature flags attendus
Donnees repliquees avec RPO et retard mesures
Ecritures et traitements asynchrones reconciliables

Chemin utilisateur
Certificat et host header valides
WAF, rate limits et allowlists alignes
Test synthetique sur lecture puis ecriture controlee
Telemetrie et alertes actives dans la region secondaire

La métrique Endpoint Status by Endpoint confirme l’état observé par Traffic Manager. Queries by Endpoint Returned, ventilée par endpoint, montre le déplacement des réponses DNS. Elle ne mesure ni les connexions actives ni les requêtes HTTP réellement servies : complétez-la avec les métriques applicatives et celles des dépendances.

Tester la bascule sans fabriquer une panne durable

En préparation, baissez le TTL suffisamment tôt pour que l’ancienne valeur expire avant l’exercice. Pendant l’incident, le diminuer n’efface pas les réponses déjà mises en cache. Préférez un test canari par nom dédié ou un endpoint de validation lorsque le routage et l’architecture le permettent.

yaml failover-validation-plan.yml
preconditions:
- secondary-readiness-gate-passed
- probe-events-correlated-with-backend
- current-dns-answer-and-ttl-captured
- rollback-owner-present

canary:
scope: controlled-client-group
verify:
- dns-answer-points-to-secondary
- tls-and-host-header-valid
- synthetic-read-and-bounded-write-succeed
- secondary-error-rate-and-latency-within-budget

stop_conditions:
- secondary-capacity-saturation
- replication-lag-outside-rpo
- rising-5xx-or-dependency-errors
- unexpected-dns-answer

N’activez pas AlwaysServe pour faire disparaître un statut rouge : ce mode contourne la décision de santé et peut renvoyer un endpoint défaillant. Ne changez pas simultanément probe, priorité, TTL et configuration backend ; vous perdriez la capacité d’attribuer l’amélioration.

Décider, valider ou rollbacker

yaml traffic-manager-decision.yml
fix_probe_or_backend:
when:
- deployed-probe-does-not-match-readiness-contract
- logs-prove-tls-host-header-status-or-timeout-failure
validate:
- endpoint-returns-online
- user-path-and-probe-both-pass

allow_automatic_failover:
when:
- primary-failure-is-proven
- secondary-capacity-and-data-readiness-are-proven
- dns-ttl-convergence-is-observed

force_bounded_failover:
when:
- primary-still-receives-harmful-traffic
- automatic-state-does-not-match-proven-failure
- change-owner-stop-conditions-and-rollback-are-ready

rollback:
action:
- restore-endpoint-status-priority-and-probe-from-iac
- reenable-primary-only-after-readiness-passes
- observe-dns-answers-for-at-least-one-ttl-window
- reconcile-writes-and-async-work-in-both-regions

Après la bascule, validez trois plans séparément : les réponses DNS renvoient la cible attendue, la cible sert réellement les requêtes, et les effets métier restent cohérents. Si la région secondaire se dégrade, revenez au dernier état IaC connu et restaurez le primaire seulement après avoir prouvé sa readiness ; une oscillation entre régions est plus difficile à récupérer qu’un failover retardé.

Conclusion

Un profil Traffic Manager Degraded est un signal de diagnostic, pas une instruction de bascule manuelle. La décision doit relier configuration déployée, contrat de probe, événements de santé, réponses DNS, TTL, capacité secondaire et état des données.

Corrigez la probe lorsqu’elle mesure le mauvais contrat, corrigez le backend lorsque l’échec est réel, laissez le failover automatique agir lorsque ses préconditions sont prouvées, et ne forcez la bascule qu’avec critères d’arrêt et rollback. La validation finale appartient autant au DNS qu’à l’application et aux effets métier.