Cloud
Azure Private Endpoint : détecter le drift Terraform, DNS et réseau avant incident
Mettre en place une lecture opérationnelle du drift entre Terraform, Private Endpoint, DNS privé, runners CI et preuves de validation avant qu’un chemin Azure privé ne casse en production.
Un Private Endpoint ne casse pas toujours au moment où il est créé. Il casse souvent plus tard, quand une zone DNS privée est déplacée, quand un runner Terraform change de réseau, quand un lien VNet disparaît, ou quand une exception publique restée ouverte masque une mauvaise résolution. Le symptôme arrive alors côté application : erreur de connexion, déploiement bloqué, backend inaccessible, Function qui ne démarre plus, ou terraform plan qui échoue sans que le changement récent semble directement lié.
Le scénario traité ici est celui d’une plateforme Azure où plusieurs services sont exposés en privé : Storage Account, Key Vault, SQL, App Service, Azure Functions ou APIs internes. Terraform crée une partie des ressources, mais l’exploitation quotidienne modifie parfois les chemins autour : DNS hub, forwarders, règles réseau, subnets de Private Endpoint, runners CI, exceptions de maintenance. L’objectif n’est pas seulement de détecter qu’un drift existe, mais de savoir s’il menace réellement un chemin de production.
Définir ce que Terraform doit garantir
Terraform ne doit pas être vu comme une preuve complète de fonctionnement. Il décrit des ressources attendues, mais il ne prouve pas toujours que le consommateur résout le bon nom, traverse le bon resolver, utilise le bon runner, ou échoue correctement depuis un réseau non autorisé. Il faut donc distinguer l’état déclaré, l’état Azure réel et la preuve opérationnelle.
Etat déclaré
Private Endpoint attendu
Private DNS Zone attendue
DNS zone group attendu
VNet link attendu
Accès public attendu: disabled ou restricted
Etat réel
Endpoint approuvé
IP privée attribuée
Zone DNS réellement liée
Enregistrements présents
Règles réseau effectives
Preuve opérationnelle
Résolution depuis le workload
Résolution depuis le runner CI
Accès HTTPS ou TCP validé
Test négatif depuis un réseau non autorisé
Retour arrière documenté Cette séparation évite un piège fréquent : conclure qu’un service est privé parce que Terraform montre un Private Endpoint, alors que le workload continue à utiliser un chemin public ou un resolver différent.
Lister les chemins consommateurs avant le diagnostic
Le même service privé peut être consommé par plusieurs chemins. Une application en VNet integration, un runner CI, une VM d’administration et un outil de support ne traversent pas forcément le même DNS. Le diagnostic doit donc commencer par une matrice simple.
Service: stordersprod.blob.core.windows.net
Consommateurs à valider
Function App prod: VNet integration vnet-app-prod
Runner Terraform: subnet ci-runners-prod
VM bastion ops: vnet-hub-ops
Poste admin: VPN vers hub
Pour chaque consommateur
Resolver utilisé
Résultat DNS attendu
IP privée attendue
Flux autorisé
Test de refus attendu depuis un réseau externe Si cette matrice n’existe pas, l’équipe risque de tester depuis l’endroit le plus pratique, pas depuis l’endroit qui représente réellement le workload. Un nslookup réussi depuis une VM hub ne prouve pas qu’une Function, un App Service ou un runner CI résout de la même manière.
Comparer Terraform et Azure sans confondre drift et incident
Un drift n’est pas automatiquement un incident. Il peut être volontaire, transitoire ou sans impact immédiat. En revanche, il devient critique quand il touche un composant qui porte la preuve de chemin privé : endpoint supprimé, zone group absent, VNet link retiré, accès public réouvert, ou IP privée qui ne correspond plus à l’enregistrement DNS utilisé.
terraform plan -refresh-only -out=tfplan.refresh
terraform show -no-color tfplan.refresh | sed -n '/private_endpoint/,+80p'
az network private-endpoint show -g rg-network-prod -n pe-stordersprod-blob --query '{name:name, provisioningState:provisioningState, subnet:subnet.id, ip:customDnsConfigs[0].ipAddresses[0]}'
az network private-endpoint dns-zone-group list -g rg-network-prod --endpoint-name pe-stordersprod-blob --query '[].{name:name, zones:privateDnsZoneConfigs[].privateDnsZoneId}' Le point important est de garder une lecture par couche. Un refresh-only peut signaler une différence de configuration, mais Azure doit confirmer si l’endpoint est approuvé, si la zone est attachée, et si l’IP privée attendue existe toujours.
Vérifier la résolution depuis les chemins utiles
Le test DNS doit être répétable et nommé. Il doit indiquer d’où il est lancé, quel FQDN est testé, quelle chaîne CNAME est attendue, et quelle IP privée est acceptable. Sinon, le diagnostic devient une collection de captures difficiles à comparer.
SERVICE_FQDN="stordersprod.blob.core.windows.net"
EXPECTED_SUFFIX="privatelink.blob.core.windows.net"
EXPECTED_PREFIX="10.50.20."
nslookup "$SERVICE_FQDN"
dig +short CNAME "$SERVICE_FQDN"
dig +short "$SERVICE_FQDN"
# Lecture attendue
# - la chaîne CNAME passe par privatelink.blob.core.windows.net
# - l'adresse finale commence par 10.50.20.
# - le test est relancé depuis le workload et depuis le runner CI Un résultat public n’est pas toujours une panne immédiate si l’accès public est encore ouvert. C’est justement le danger : la plateforme peut fonctionner pendant que la preuve de chemin privé est déjà fausse. Le prochain durcissement réseau transformera alors un drift silencieux en incident.
Contrôler les exceptions publiques et les chemins résiduels
Le drift le plus trompeur est celui qui laisse tout fonctionner. Une règle firewall, une exception de service de confiance ou un accès public temporaire peut masquer une erreur DNS. Avant de fermer ou de modifier un Private Endpoint, il faut vérifier que la réussite vient du chemin prévu.
az storage account show -g rg-app-prod -n stordersprod --query '{publicNetworkAccess:publicNetworkAccess, defaultAction:networkRuleSet.defaultAction, bypass:networkRuleSet.bypass}'
az storage account network-rule list -g rg-app-prod -n stordersprod --query '{ipRules:ipRules[].ipAddressOrRange, virtualNetworkRules:virtualNetworkRules[].virtualNetworkResourceId}' La bonne question n’est pas seulement “est-ce que ça marche ?”. Il faut demander “par quel chemin ça marche ?”. Un test positif depuis un réseau non autorisé doit être traité comme un signal de dérive, même si l’application ne se plaint pas encore.
Mettre le runner Terraform dans le périmètre
Les équipes valident souvent la résolution depuis le workload, puis oublient le runner Terraform. Pourtant, si le backend, les providers ou les scripts de validation doivent atteindre des services privés, le runner devient un consommateur à part entière. Un changement de subnet ou de DNS sur les runners peut bloquer init, plan, apply ou les contrôles post-déploiement.
Contrat runner Terraform
Réseau d’exécution connu
Resolver DNS documenté
Accès au backend state validé
Accès aux services privés nécessaires aux tests validé
Identité CI séparée des comptes humains
Procédure de maintenance si le runner principal est indisponible Ce contrat évite de traiter chaque panne CI comme un problème Terraform. Parfois, le code n’a pas changé : c’est le chemin réseau du runner qui n’est plus celui utilisé dans les preuves précédentes.
Transformer le diagnostic en garde-fou de changement
Le contrôle utile n’est pas un audit annuel. Il doit devenir une étape courte avant les changements qui touchent Private Endpoint, Private DNS Zone, routage, firewall, runner CI ou accès public. L’objectif est de bloquer les changements ambigus, pas de ralentir chaque déploiement.
Avant changement
Identifier les FQDN concernés
Lister les consommateurs critiques
Capturer DNS et accès depuis workload + runner
Vérifier l’état Terraform refresh-only
Vérifier les exceptions publiques résiduelles
Après changement
Rejouer les mêmes tests depuis les mêmes chemins
Confirmer le test négatif depuis un réseau externe
Documenter IP privée, zone, lien VNet et résultat applicatif
Garder le rollback DNS/réseau explicite Le garde-fou doit rester assez court pour être utilisé. Les tests exhaustifs finissent ignorés. Les cinq ou six preuves qui protègent réellement le chemin privé doivent être faciles à relancer.
Prévoir le rollback DNS avant de toucher au réseau
Un rollback de Private Endpoint ne consiste pas toujours à supprimer la ressource. Dans beaucoup de cas, le retour arrière le plus propre consiste à restaurer un lien de zone, revenir sur un forwarder, remettre une règle réseau temporaire ou rebasculer un runner vers son réseau précédent. Cette décision doit être écrite avant la fenêtre de changement.
Rollback possible
Restaurer le VNet link précédent
Revenir au forwarder DNS précédent
Réactiver temporairement une règle réseau limitée
Rebasculer le runner Terraform vers le subnet validé
Rejouer les tests DNS depuis workload et runner
Supprimer l’exception temporaire après stabilisation Sans rollback explicite, l’équipe risque de rouvrir trop largement l’accès public pour rétablir le service. Le retour arrière doit donc être aussi ciblé que le diagnostic.
Conclusion
Le drift autour d’un Private Endpoint est rarement une seule différence Terraform. C’est souvent un écart entre ressource déclarée, état Azure réel et preuve depuis les bons chemins. Pour garder un réseau privé exploitable, il faut relier Terraform, DNS privé, runners CI, exceptions publiques et tests applicatifs.
La base saine consiste à documenter les consommateurs, vérifier la chaîne DNS depuis le workload et le runner, comparer l’état Terraform avec l’état Azure, puis tester aussi le refus depuis les chemins non autorisés. Avec ces preuves, un changement Private Endpoint devient une décision maîtrisée plutôt qu’un pari sur une architecture supposée privée.