Cloud

Azure Functions : diagnostiquer un endpoint HTTP privé avant de changer le code

Construire un runbook opérationnel pour les pannes Azure Functions en accès privé en séparant DNS, Private Endpoint, restrictions réseau, storage privé, logs Application Insights et rollback.

11 juin 2026 azurefunctionsprivate-endpointdnskqllogsmonitoringrunbookidentityrollbackautomation

Une Azure Function exposée en privé peut tomber en panne sans que le code soit en cause. Le hostname peut résoudre vers l’adresse publique, le Private Endpoint peut être correct mais absent du réseau appelant, les access restrictions peuvent bloquer le trafic, le runtime peut ne pas démarrer parce que le storage privé est injoignable, ou l’application peut répondre 403, 502, 503 ou timeout avant même d’entrer dans la fonction.

Le cas d’usage est une API interne servie par un HTTP trigger Azure Functions. Les consommateurs passent par un réseau privé, parfois derrière Application Gateway ou APIM interne. Une modification vient d’être appliquée sur DNS, networking, storage, identité managée, configuration applicative ou package de déploiement. Avant de redéployer le code ou d’ouvrir l’accès public, le runbook doit prouver où la requête s’arrête.

Lire le chemin privé comme une chaîne unique

Le diagnostic est plus fiable si l’équipe dessine le chemin complet avant de changer un paramètre. Une Function App privée n’est pas seulement une URL : c’est une combinaison de DNS, Private Link, règles d’accès, runtime Functions, storage de plateforme, identité et logs.

text azure-functions-private-http-path.txt
Client ou probe interne
Résout api.internal.example.com
Appelle le hostname attendu avec le bon host header

Entrée privée
Application Gateway, APIM interne ou client direct
Préserve TLS/SNI et correlation ID

Function App
Private Endpoint sur le site HTTP
Access restrictions cohérentes avec le réseau appelant
Runtime Functions démarré

Storage et dépendances
AzureWebJobsStorage joignable par le chemin privé attendu
Key Vault, files, queues ou APIs aval résolus en privé si requis

Observabilité
Application Insights ou Log Analytics reçoit traces, requests et exceptions
Le rollback cible la couche réellement modifiée

Cette carte empêche une correction trop large. Un 403 causé par une règle réseau ne se corrige pas avec un redéploiement. Un runtime qui ne démarre pas parce que le storage privé est bloqué ne se corrige pas en modifiant Application Gateway.

Classer le symptôme avant l’action

La première question n’est pas “la fonction marche-t-elle ?”. Elle devient : “le hostname privé atteint-il le site Functions, le runtime est-il démarré, et la fonction a-t-elle exécuté la requête ?”.

text azure-functions-private-http-symptoms.txt
Symptôme
DNS retourne une adresse publique ou vide
  Vérifier zone privatelink.azurewebsites.net, liens VNet et forwarding DNS hybride

curl retourne 403 immédiatement
  Vérifier access restrictions, private endpoint, route source et éventuel APIM/Application Gateway

curl retourne 502 ou 503
  Vérifier état runtime, worker process, configuration Functions et disponibilité du storage

Aucune request n'apparaît dans Application Insights
  Revenir vers DNS, gateway, APIM, access restrictions ou private endpoint

La request apparaît mais échoue en exception
  Lire traces, exceptions, identité managée, Key Vault et dépendances aval

Le runtime ne démarre pas après changement réseau
  Valider AzureWebJobsStorage, DNS privé du storage et paramètres réseau du compte

Cette classification donne une règle simple : ne pas toucher au code tant que l’exécution de la fonction n’est pas visible dans les logs.

Prouver DNS, TLS et accès depuis le réseau consommateur

Le test doit partir du même réseau que le consommateur réel : subnet applicatif, runner de probe, VM de diagnostic ou environnement APIM interne. Un test depuis un poste public peut donner une réponse trompeuse.

bash 01-functions-private-dns-http-check.sh
HOSTNAME=api.internal.example.com
PATH=/api/health
CORRELATION_ID="ops-$(date +%Y%m%d%H%M%S)"

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

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

curl -vk "https://$HOSTNAME$PATH" -H "x-correlation-id: $CORRELATION_ID" -H "x-naxaya-check: private-functions"

echo "correlation_id=$CORRELATION_ID"

Si la résolution n’est pas privée, corrige DNS avant toute autre action. Si TLS ou le host header échoue, regarde le point d’entrée. Si le curl retourne 403 avant d’atteindre les logs Functions, le problème est probablement réseau ou restriction d’accès.

Vérifier la Function App et son storage privé

Une Function App peut accepter une route privée mais rester inutilisable si le runtime n’arrive pas à joindre son storage de plateforme. C’est fréquent après durcissement réseau : le site est privé, mais AzureWebJobsStorage ou le file share associé ne résout plus ou n’est pas autorisé depuis le bon chemin.

bash 02-functions-platform-checks.sh
APP_RG=rg-prod-app
APP_NAME=func-prod-orders

az functionapp show -g "$APP_RG" -n "$APP_NAME" --query "{state:state, httpsOnly:httpsOnly, defaultHostName:defaultHostName, outboundIpAddresses:outboundIpAddresses}" -o table

az functionapp config access-restriction show -g "$APP_RG" -n "$APP_NAME" -o table

az functionapp config appsettings list -g "$APP_RG" -n "$APP_NAME" --query "[?name=='AzureWebJobsStorage' || contains(name, 'WEBSITE_') || contains(name, 'FUNCTIONS_')].[name,value]" -o table

az network private-endpoint-connection list --id "$(az functionapp show -g "$APP_RG" -n "$APP_NAME" --query id -o tsv)" --query "[].{name:name,status:privateLinkServiceConnectionState.status}" -o table

Le but n’est pas d’exposer les secrets dans un ticket, mais de vérifier les dimensions : runtime actif, restrictions attendues, paramètres réseau présents, Private Endpoint approuvé et storage joignable par DNS privé.

Corréler requests, traces et exceptions en KQL

Quand la requête atteint la Function App, Application Insights doit montrer au moins une request, une trace ou une exception sur la fenêtre d’incident. La corrélation par hostname, URL et correlation ID évite de mélanger un vrai échec privé avec du bruit applicatif.

kusto 03-functions-private-http-correlation.kql
let Window = 2h;
let Host = "api.internal.example.com";
let CorrelationId = "ops-20260611080000";
let Req =
requests
| where timestamp > ago(Window)
| where url has Host or tostring(customDimensions["x-correlation-id"]) == CorrelationId
| project timestamp, Source="request", name, resultCode, success, operation_Id, url, cloud_RoleName;
let Tr =
traces
| where timestamp > ago(Window)
| where message has_any (Host, CorrelationId, "Host lock", "storage", "listener", "Starting", "Stopping", "Function")
| project timestamp, Source="trace", message, severityLevel, operation_Id, cloud_RoleName;
let Ex =
exceptions
| where timestamp > ago(Window)
| project timestamp, Source="exception", message=outerMessage, severityLevel, operation_Id, cloud_RoleName;
Req
| union Tr, Ex
| order by timestamp desc

Lecture rapide : aucune request avec un curl corrélé renvoie vers DNS, edge privé ou access restrictions ; request en 403 ou 503 renvoie vers plateforme et configuration ; request avec exception renvoie vers code, identité ou dépendance.

Borner rollback et correction

Le rollback doit restaurer la couche modifiée, pas tout l’environnement. Si un changement DNS a cassé la résolution privée, restaure la zone ou le forwarder. Si une restriction d’accès a bloqué APIM, restaure la règle. Si le dernier package déclenche une exception après entrée dans la fonction, rollback le déploiement.

text functions-private-http-rollback-matrix.txt
Changement récent
DNS privé
  Rollback: restaurer l'ancien record, lien VNet ou forwarder
  Preuve: nslookup privé + curl avec correlation ID

Access restriction
  Rollback: restaurer la règle source précédente
  Preuve: request visible dans Application Insights

Storage privé
  Rollback: restaurer autorisation réseau ou DNS storage précédent
  Preuve: runtime démarré + absence d'erreurs Host lock/storage

Package applicatif
  Rollback: revenir au package ou slot validé
  Preuve: même request réussie avec operation_Id conservé

Conclusion

Une Azure Function privée doit être diagnostiquée comme un chemin de production, pas comme une simple fonction serverless. DNS, Private Endpoint, restrictions, runtime, storage et logs doivent être séparés avant de modifier le code.

La règle opérationnelle est volontairement stricte : tant qu’aucune request corrélée n’apparaît dans les logs, reste sur réseau et plateforme ; dès qu’elle apparaît, bascule vers runtime, identité, dépendances ou code. Cette séparation réduit les ouvertures publiques temporaires, les redéploiements inutiles et les rollbacks trop larges.