Cloud

Azure SQL : diagnostiquer un endpoint privé avant de modifier la base

Un runbook opérationnel pour qualifier les pannes Azure SQL en accès privé en séparant DNS, Private Endpoint, firewall, identité, logs SQL et rollback.

14 juin 2026 azuresqlprivate-endpointdnskqllogsmonitoringrunbookidentityrollbackfirewall

Une base Azure SQL expose souvent un symptôme ambigu : timeout depuis l’application, erreur de connexion, refus d’authentification, absence de logs côté base ou retour 40615 lié au firewall. Quand le serveur est placé derrière Private Endpoint, ces signaux ne doivent pas être lus comme une panne SQL unique. Le problème peut venir de DNS privé, du sous-réseau appelant, d’un endpoint non approuvé, d’une règle réseau encore publique, d’une identité managée, d’un groupe Azure AD ou d’un changement de chaîne de connexion.

Le cas d’usage est une application interne, un job d’automatisation ou une API privée qui doit accéder à Azure SQL sans exposition publique. L’objectif du runbook est de prouver où la connexion s’arrête avant de changer le schéma, de redéployer l’application, d’ouvrir le serveur SQL ou d’élargir les droits d’une identité.

Lire Azure SQL comme un chemin complet

Le diagnostic doit suivre la chaîne réelle entre le consommateur et la base. Valider uniquement le serveur SQL dans le portail ne suffit pas si le workload ne résout pas le même nom, ne sort pas par le même réseau ou n’utilise pas la même identité.

text azure-sql-private-path.txt
Consommateur
App Service, Function, API, runner CI ou VM de diagnostic
Résout le FQDN SQL depuis le même réseau que le workload
Utilise la chaîne de connexion et l'identité réelles

DNS privé
server.database.windows.net doit suivre la chaîne privatelink.database.windows.net
La réponse finale doit être une adresse privée du VNet attendu

Chemin réseau
Private Endpoint approuvé pour le serveur SQL
Zone privée liée au VNet consommateur ou forwarding hybride valide
Accès public cohérent avec la cible de sécurité

Identité et autorisation
SQL login, Microsoft Entra ID, managed identity ou service principal
Droits minimaux sur la base, pas seulement sur le serveur

Preuves
Test depuis le réseau consommateur
Logs SQL, métriques de connexion, traces applicatives et correlation ID

Cette lecture évite deux raccourcis dangereux : ouvrir le firewall parce que l’application voit un timeout, ou modifier les droits SQL alors que le nom résout encore vers un endpoint public.

Classer le symptôme avant de corriger

Le premier tri consiste à séparer les pannes de chemin privé, les refus réseau et les refus d’identité. Le message d’erreur seul ne suffit pas ; il doit être lu avec le point de test.

text azure-sql-private-symptoms.txt
Symptôme observé
DNS retourne une adresse publique
  Vérifier la zone privatelink.database.windows.net, le lien VNet et les forwarders DNS

Timeout avant login
  Vérifier Private Endpoint, routage, NSG, firewall local et test depuis le réseau consommateur

Erreur 40615 ou firewall
  Vérifier public network access, règles firewall et source réellement vue par SQL

Login failed ou principal introuvable
  Vérifier identité réelle, méthode d'authentification, utilisateur contenu dans la base et groupes Entra ID

Aucune trace côté SQL
  Revenir à DNS, routage, endpoint public ou chaîne de connexion

Echec après changement Terraform ou pipeline
  Comparer Private Endpoint, private DNS zone group, firewall SQL et identité déployée

La règle d’exploitation est simple : tant que le FQDN SQL ne résout pas en privé depuis le réseau consommateur, la correction SQL ou applicative est prématurée.

Tester depuis le bon réseau

Le test doit être exécuté depuis une VM de diagnostic, un runner privé, le subnet applicatif ou un bastion d’exploitation qui partage le DNS du workload. L’idée n’est pas de prouver que SQL répond depuis votre poste, mais que le chemin de production est cohérent.

bash 01-azure-sql-private-check.sh
SERVER=sql-prod-orders
DATABASE=orders
HOSTNAME="$SERVER.database.windows.net"

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

openssl s_client -connect "$HOSTNAME:1433" -servername "$HOSTNAME" </dev/null 2>/dev/null | openssl x509 -noout -subject -issuer

az sql db show-connection-string --client ado.net --server "$SERVER" --name "$DATABASE" --auth-type ADIntegrated

sqlcmd -S "$HOSTNAME" -d "$DATABASE" -G -l 10 -Q "select @@servername as server_name, db_name() as database_name, sysdatetimeoffset() as checked_at;"

Si sqlcmd n’est pas disponible sur le point de test, gardez au minimum nslookup, dig, openssl et une tentative applicative corrélée. Le plus important est de conserver l’heure, le hostname, l’identité attendue et l’erreur exacte.

Vérifier la plateforme sans ouvrir le serveur

Les commandes suivantes donnent une lecture rapide de l’état réseau et de la configuration SQL sans modifier le périmètre d’exposition.

bash 02-azure-sql-platform-checks.sh
RG=rg-prod-data
SERVER=sql-prod-orders

az sql server show -g "$RG" -n "$SERVER" --query "{fqdn:fullyQualifiedDomainName, publicNetworkAccess:publicNetworkAccess, minimalTlsVersion:minimalTlsVersion}" -o jsonc

SQL_ID=$(az sql server show -g "$RG" -n "$SERVER" --query id -o tsv)

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

az network private-dns zone show -g "$RG" -n privatelink.database.windows.net --query "{name:name, records:numberOfRecordSets}" -o jsonc

az sql server firewall-rule list -g "$RG" -s "$SERVER" -o table
az sql server ad-admin list -g "$RG" -s "$SERVER" -o table

Les dérives typiques sont visibles ici : Private Endpoint en attente, zone privée absente du VNet consommateur, accès public encore activé par exception historique, admin Entra ID non configuré ou règle firewall créée pour un ancien runner.

Corréler les erreurs dans Log Analytics

Si les diagnostics SQL sont envoyés vers Log Analytics, une requête courte aide à séparer erreurs réseau, erreurs d’authentification et activité absente. Les noms exacts de tables peuvent varier selon les paramètres de diagnostic, mais la logique reste la même : partir de la fenêtre, du serveur, de la base et du message.

kusto 03-azure-sql-private-errors.kql
let Window = 2h;
let Server = "sql-prod-orders";
let Database = "orders";
AzureDiagnostics
| where TimeGenerated > ago(Window)
| where ResourceProvider == "MICROSOFT.SQL"
| where Resource has Server or database_name_s == Database
| where action_name_s has_any ("DATABASE AUTHENTICATION", "LOGOUT", "BATCH COMPLETED")
 or error_number_d in (40615, 18456, 18452, 18470)
 or statement_s has_any ("Login failed", "firewall", "denied")
| project TimeGenerated, Resource, database_name_s, action_name_s, error_number_d, succeeded_s, session_server_principal_name_s, client_ip_s, statement_s
| order by TimeGenerated desc

Lecture rapide : absence de ligne pour le test oriente vers DNS, routage ou mauvais endpoint ; 40615 oriente vers firewall ou accès public ; 18456 et assimilés orientent vers identité, utilisateur contenu, groupe Entra ID ou secret obsolète.

Choisir un rollback minimal

Le rollback doit restaurer la couche qui a réellement changé, pas contourner toute la chaîne privée.

text azure-sql-private-rollback.txt
Changement récent
Private DNS zone, lien VNet ou forwarding
  Rollback: restaurer l'ancien lien ou le forwarding précédent
  Preuve: le FQDN retourne l'adresse privée depuis le workload

Private Endpoint ou accès public
  Rollback: revenir au statut Private Endpoint et publicNetworkAccess précédents
  Preuve: test sqlcmd corrélé et logs SQL visibles

Identité managée, groupe Entra ID ou secret
  Rollback: restaurer l'identité ou le droit au scope précédent
  Preuve: même identité se connecte sans rôle plus large que nécessaire

Chaîne de connexion ou variable d'environnement
  Rollback: restaurer serveur, base, auth mode et options TLS précédents
  Preuve: la connexion utilise le FQDN privé attendu

Conclusion

Un incident Azure SQL privé se traite comme un chemin d’exploitation, pas comme une panne de base isolée. Le bon ordre est stable : résolution DNS depuis le réseau consommateur, Private Endpoint, exposition publique, authentification, logs et rollback limité.

Cette méthode évite les réactions trop larges. On corrige DNS si le nom sort en public, le Private Endpoint si le chemin privé manque, le firewall si SQL voit une source inattendue, l’identité si la connexion arrive mais échoue, et la chaîne applicative seulement quand les preuves réseau et plateforme sont propres.