guest@6admin.io:~$

Votre zone DNS est déjà un inventaire: la collection log0u7.dns

Chaque inventaire statique que j’ai croisé a commencé comme une vérité pour devenir une fiction en un trimestre. Les machines bougent, le fichier d’inventaire non. Les plugins cloud règlent ça en demandant au cloud, mais mes flottes vivent entre datacenters et FAI, derrière le DNS que l’entreprise fait déjà tourner. D’où une observation inconfortable: la zone DNS contient déjà l’inventaire. Chaque hôte a un enregistrement; ce qui manque, c’est qu’Ansible le lise.

Alors j’ai écrit log0u7.dns (v2.0.1, MIT): une collection Ansible dont le plugin d’inventaire construit les hôtes depuis des enregistrements DNS. La contrainte de design qui a tout façonné: pas de transfert de zone (AXFR). AXFR est la porte qu’on ne laisse pas ouverte sur une zone publique et l’exiger rendrait le plugin inutile contre exactement les serveurs DNS que vous ne contrôlez pas.

Quatre méthodes de découverte, combinables

  • Manifest TXT: _ansible-hosts.<zone> TXT "web-01,web-02,db-01", la norme historique, un enregistrement qui liste la flotte.
  • Enregistrements SRV: SRV _ansible._tcp.<zone> avec les targets comme hôtes; un port non-22 dans le target devient ansible_port automatiquement.
  • DNS-SD (RFC 6763): une promenade PTR au nom du service pour énumérer les instances, puis un SRV par instance. C’est la partie introuvable ailleurs: j’ai écrit une table de prior art dans la doc d’architecture et le résumé honnête est qu’aucune des implémentations sans AXFR (2016 Node.js, 2016 Python, 2019 Go) n’utilise DNS-SD. C’est aussi celle qui passe à l’échelle: un enregistrement par instance, des requêtes standards, rien de bespoke.
  • Patterns de nommage: prod-web-{:02d} sondé sur une plage numérique, pour les flottes provisionnées par script et donc aux noms en forme de script.

Les quatre peuvent être activées ensemble; leurs listes d’hôtes fusionnent, dédupliquées.

Métadonnées: les enregistrements TXT sont vos hostvars

La résolution par hôte se fait en parallèle: enregistrement A, puis repli AAAA, puis un TXT à <host>.<zone> parsé en paires clé=valeur. Le parseur type ce qu’il trouve: booléens true/false, entiers, tableaux JSON, listes à virgules, flags nus. Les clés réservées (ansible_host, ansible_port, dns_hostname) ne peuvent pas être écrasées par TXT, donc un enregistrement de zone ne peut pas détourner la connectivité.

Le grouping vient de la convention de nommage elle-même: prod-web-01 finit dans prod, web, prod_web et ce que vos group_mappings disent (web: [webservers, frontend]). La convention que vous imposez déjà sur les hostnames devient le grouping que vous obtenez dans Ansible, gratuitement.

Le détail de concurrence qui mérite d’être publié

La résolution des hôtes tourne sur un ThreadPoolExecutor (10-15 workers par défaut) et chaque worker reçoit son propre Resolver dnspython. La raison est ennuyeuse et importante: les résolveurs dnspython ne sont pas thread-safe et le mode d’échec d’un partage unique est une corruption intermittente qui ressemble à un problème de serveur DNS. Un résolveur par thread; le parallélisme vient du pool, pas du partage d’état.

Le cache n’est pas inventé non plus: le plugin utilise le fragment natif inventory_cache d’Ansible, donc n’importe quel backend de cache (jsonfile, redis ) et son TTL marchent d’emblée.

Le chemin inverse: inventaire vers zone

La collection livre aussi scripts/inventory_to_dns.py (432 lignes): il lit n’importe quel inventaire, statique ou dynamique, via ansible-inventory --list et émet un fichier de zone compatible BIND (SOA/NS, TXT/SRV de découverte, A/AAAA par hôte, un TXT par variable). Migrer vers DNS-comme-inventaire est donc une porte à sens unique que l’on ouvre lentement: générer la zone depuis ce qui existe aujourd’hui, laisser les deux inventaires cohabiter, basculer quand ils se ressemblent.

Le convertisseur passe aussi des heuristiques de fuite de secrets sur les noms de variables avant de les publier (une variable nommée api_key est signalée; les références vault:// et openbao:// sont exemptées parce que ce sont des pointeurs, pas du matériel).

La mise en garde honnête

Si votre zone est publique, votre inventaire est public: hostnames, IPs et chaque TXT de métadonnée deviennent lisibles par quiconque interroge le résolveur. La doc sécurité le dit crûment: DNS-comme-inventaire, c’est pour des hôtes que vous acceptez de publier ou pour des zones sur des résolveurs privés avec le même plugin pointé dessus. Les résolveurs sont configurables; les défauts sont publics exprès, parce que les tests d’intégration tournent contre un dnsmasq local et les flottes publiques contre le DNS public.

Le DNS savait déjà

  • L’inventaire existe déjà; il s’appelle DNS. Arrêtez d’en maintenir une seconde copie en YAML.
  • AXFR est un privilège, pas une dépendance. Concevez le chemin de lecture pour marcher sans aucun changement côté serveur.
  • Prior art d’abord, nouveauté ensuite. La promenade DNS-SD est le seul morceau réellement neuf et elle existe parce que j’ai tabulé ce que 2016 et 2019 ne faisaient pas.
  • Threads + état partagé = le bug qui accuse le réseau. Des résolveurs par thread coûtent moins cher que des mystères intermittents.

[edit: 2026] L’implémentation Ansible de tout ceci: le rôle unbound .