Cloud

Azure Service Bus : diagnostiquer un endpoint privé avant de toucher aux queues

Un runbook opérationnel pour qualifier les incidents Azure Service Bus en accès privé en séparant DNS, Private Endpoint, identité, firewall, métriques, logs et rollback.

15 juin 2026 azureservice-busprivate-endpointdnskqllogsmonitoringrunbookidentityrollbackmessaging

Un incident Azure Service Bus privé se présente rarement comme une panne unique. Un publisher peut voir des timeouts, un consumer peut ne plus recevoir de messages, une application peut retourner 401 ou 403, et les métriques peuvent montrer une queue qui se remplit sans erreur claire côté code. Quand le namespace est exposé par Private Endpoint, la bonne réaction n’est pas de redéployer le worker ni de modifier la queue à l’aveugle.

Le cas d’usage est une application interne qui publie ou consomme des messages depuis un réseau privé : App Service, Function, AKS, Container Apps, VM ou runner d’automatisation. L’objectif du runbook est de prouver si l’incident vient du chemin privé, de l’identité, des règles réseau, de la configuration Service Bus ou du traitement applicatif.

Lire Service Bus comme un chemin de messagerie

Service Bus ajoute une couche métier au diagnostic réseau. Il ne suffit pas de savoir si le namespace répond. Il faut aussi vérifier le type d’opération, l’entité ciblée, l’identité utilisée et l’effet sur le backlog.

text service-bus-private-path.txt
Workload
Publisher, consumer, Function trigger, worker ou pipeline
Resolution du FQDN depuis le meme reseau que le workload
Identite ou SAS réellement utilisee par l'application

DNS prive
namespace.servicebus.windows.net doit suivre privatelink.servicebus.windows.net
La reponse finale doit etre une adresse privee du VNet attendu

Plateforme Service Bus
Private Endpoint approuve
Public network access coherent avec la cible de securite
Queue, topic, subscription et dead-letter queue dans l'etat attendu

Preuves
Horodatage du test
Operation envoyee ou recue
Metrics ActiveMessages, DeadletteredMessages, IncomingRequests
Logs et erreurs applicatives

Cette lecture évite deux raccourcis classiques : augmenter les droits alors que le nom résout encore en public, ou purger une queue alors que le consumer n’a simplement plus accès au namespace.

Classer le symptôme avant l’action

Le message d’erreur doit toujours être lu avec le point de test. Une absence de consommation peut venir du réseau, d’un lock de message, d’un filtre de subscription, d’une identité sans rôle ou d’un traitement applicatif qui échoue après réception.

text service-bus-symptoms.txt
Symptome observe
Timeout ou nom non resolu
  Verifier DNS prive, Private Endpoint, routage et firewall local

401 ou 403
  Verifier identite reelle, RBAC Service Bus Data Sender/Receiver/Owner ou SAS

Messages publies mais non consommes
  Verifier consumer actif, subscription, filtre, lock duration, dead-letter et erreurs applicatives

Aucune ligne de log Service Bus
  Revenir au FQDN, au endpoint public, au reseau source ou a la chaine de connexion

Backlog augmente apres changement Terraform
  Comparer Private Endpoint, publicNetworkAccess, role assignments et entites deployees

La règle d’exploitation est stable : tant que le FQDN Service Bus ne résout pas en privé depuis le réseau consommateur, toute correction côté queue ou code est prématurée.

Tester depuis le bon réseau

Le test doit être exécuté depuis un point qui partage le DNS et le chemin réseau du workload. Un poste local en VPN peut aider, mais il ne remplace pas une VM de diagnostic, un pod, un runner privé ou le subnet applicatif.

bash 01-service-bus-private-check.sh
RG=rg-prod-messaging
NAMESPACE=sb-prod-orders
QUEUE=orders-in
HOSTNAME="$NAMESPACE.servicebus.windows.net"

nslookup "$HOSTNAME"
dig +short "$HOSTNAME"

az servicebus namespace show -g "$RG" -n "$NAMESPACE" --query "{name:name, publicNetworkAccess:publicNetworkAccess, provisioningState:provisioningState}" -o jsonc

SB_ID=$(az servicebus namespace show -g "$RG" -n "$NAMESPACE" --query id -o tsv)

az network private-endpoint-connection list --id "$SB_ID" --query "[].{name:name,status:privateLinkServiceConnectionState.status,description:privateLinkServiceConnectionState.description}" -o table

az servicebus queue show -g "$RG" --namespace-name "$NAMESPACE" -n "$QUEUE" --query "{status:status, active:countDetails.activeMessageCount, deadletter:countDetails.deadLetterMessageCount, lockDuration:lockDuration}" -o jsonc

Ces commandes ne prouvent pas que l’application consomme correctement, mais elles séparent rapidement un namespace indisponible, un endpoint privé non approuvé, un accès public incohérent et une queue déjà saturée ou désactivée.

Vérifier l’identité réelle

En production, Service Bus est souvent consommé avec une identité managée, un service principal ou une SAS historique. Le diagnostic doit identifier l’identité effectivement utilisée par le runtime, pas celle prévue dans l’architecture.

bash 02-service-bus-identity-check.sh
SB_ID=$(az servicebus namespace show -g "$RG" -n "$NAMESPACE" --query id -o tsv)
PRINCIPAL_ID=<principal-id-du-workload>

az role assignment list --assignee "$PRINCIPAL_ID" --scope "$SB_ID" --query "[].{role:roleDefinitionName,scope:scope}" -o table

az servicebus namespace authorization-rule list -g "$RG" --namespace-name "$NAMESPACE" -o table

Si le workload utilise encore une SAS, le runbook doit le rendre visible. Une SAS expirée ou copiée depuis un ancien namespace produit un incident très différent d’une identité managée sans rôle Azure Service Bus Data Receiver.

Corréler backlog, erreurs et refus

Les métriques donnent la forme de l’incident : backlog qui monte, dead-letter qui augmente, requêtes entrantes absentes ou erreurs côté namespace. Les logs et traces applicatives donnent ensuite la cause.

kusto 03-service-bus-private-errors.kql
let Window = 2h;
let Namespace = "sb-prod-orders";
AzureDiagnostics
| where TimeGenerated > ago(Window)
| where ResourceProvider == "MICROSOFT.SERVICEBUS"
| where Resource has Namespace
| where OperationName has_any ("Send", "Receive", "Complete", "Abandon", "DeadLetter", "RenewLock")
 or ResultType !in ("Success", "Succeeded")
| project TimeGenerated, Resource, OperationName, ResultType, ResultDescription, ActivityId, CallerIPAddress, Identity=tostring(Identity)
| order by TimeGenerated desc

Lecture rapide : aucune ligne pour le test ramène vers DNS, Private Endpoint ou chaîne de connexion ; 401/403 oriente vers identité ou SAS ; erreurs après Receive orientent vers lock, dead-letter ou traitement applicatif.

Choisir un rollback borné

Le rollback ne doit pas supprimer les preuves ni masquer l’origine. Il doit restaurer la couche modifiée : DNS, Private Endpoint, identité, configuration de queue ou version applicative.

text service-bus-rollback.txt
Changement recent
Private DNS ou lien de zone
  Rollback: restaurer le lien ou le forwarding precedent
  Preuve: FQDN resolu en prive depuis le workload

Private Endpoint ou publicNetworkAccess
  Rollback: revenir au statut reseau precedent
  Preuve: requete envoyee ou recue avec logs Service Bus visibles

Role assignment ou SAS
  Rollback: restaurer l'identite ou la cle precedente seulement pour la fenetre decidee
  Preuve: meme operation reussit sans droit plus large

Worker, Function ou configuration queue
  Rollback: revenir a la version applicative precedente
  Preuve: backlog se stabilise et dead-letter n'augmente plus

Conclusion

Un incident Azure Service Bus en réseau privé se traite comme une chaîne complète : DNS, Private Endpoint, exposition publique, identité, entité de messagerie, métriques, logs et rollback. Cette méthode évite de confondre une panne de chemin privé avec un bug consumer, ou un refus d’identité avec une queue bloquée.

La décision devient plus simple : corriger DNS si le namespace sort en public, Private Endpoint si le chemin privé manque, RBAC ou SAS si l’appel atteint Service Bus mais échoue, et l’application seulement quand les preuves plateforme sont propres.