--- - name: Appliquer le groupe serveur_debian hosts: serveur_debian become: true # Le verrou dpkg est tenu par les maj automatiques de Debian, par vagues, plusieurs # minutes apres le premier demarrage. Pose ICI plutot que dans chaque role : toute # tache apt du play en herite, y compris celles des roles inclus. module_defaults: ansible.builtin.apt: lock_timeout: 300 gather_facts: true pre_tasks: - name: Vérifier que la cible est Debian ansible.builtin.assert: that: - ansible_facts.distribution == "Debian" fail_msg: "Ce playbook est prévu pour Debian." # Résolveur d'AMORÇAGE, posé avant `common_packages` — donc avant le premier `apt`. # Sans lui, le déploiement échoue avant d'avoir commencé : le gabarit doré transporte # un `/etc/resolv.conf` figé, et le `dns-nameservers` écrit par cloud-init reste sans # effet faute de `resolvconf` (qu'on ne peut pas installer sans résolution — la boucle # se referme). Mesuré le 2026-08-06 sur deux VM neuves. # # PASSAGE DE RELAIS : `client_resolveur` reprend ce fichier plus tard pour le basculer # vers `127.0.0.1`. La garde ci-dessous le respecte — sans elle, chaque déploiement # défairait la bascule, et deux rôles se disputeraient le même fichier sans fin. # SOURCE D'ARTEFACTS D'AMORÇAGE, posée avant le premier `apt` — symétrique exacte du # résolveur d'amorçage ci-dessous, et pour la même raison de fond : LA PREMIÈRE # MACHINE D'UN ÉCOSYSTÈME N'A NI RÉSOLVEUR NI CACHE, ET C'EST ELLE QUI DOIT LES # CONSTRUIRE. # # Mesuré le 2026-08-28 sur `ops-01`, première machine de la reconstruction de # Chezlepro. Le socle restait bloqué sur son premier `apt update`, sans message qui # parle de réseau : # # sortie Internet TCP 443 OK # DNS UDP 53 -> 9.9.9.9 MUET # # Le DNS sortant est fermé PAR CONCEPTION — un tenant résout chez lui, son DNS ne # traverse jamais la frontière. Or apt vise `deb.debian.org` PAR SON NOM, et le cache # de l'écosystème n'existe pas encore. # # UN MANDATAIRE HTTP RÉSOUT CE QUE LE CLIENT NE PEUT PAS RÉSOUDRE : apt lui envoie # l'URL absolue, et c'est LUI qui traduit le nom. La machine n'a donc besoin d'aucun # DNS pour installer ses paquets — seulement d'une ADRESSE. # # C'EST DE LA FILIATION, PAS UNE RUSTINE (docs/filiation-emancipation.md). L'hébergeur # nourrit la première machine de son locataire le temps que celui-ci monte son propre # cache. L'emprunt est DÉCLARÉ — l'intrant nomme l'amont — et il s'efface de lui-même : # `client_artefacts` écrit `00-setops-artefacts`, qui trie APRÈS ce fichier-ci, donc # gagne dès que l'écosystème a sa propre source. Le plancher reste dessous, comme # `/etc/hosts` reste sous le DNS. # # Aucun flux à ouvrir : `serveur_cache_site` accepte déjà le 3142 depuis # `voisins_site`, qui résout les SUPERNETS des tenants — donc toute machine, pas # seulement leur cache. Vérifié depuis `ops-01` : HTTP 200 en 0,158 s. - name: Poser la source d'artefacts d'amorçage (avant tout apt) ansible.builtin.copy: dest: /etc/apt/apt.conf.d/00-setops-amorcage-artefacts owner: root group: root mode: "0644" content: | // GÉNÉRÉ par Set-OPS (socle) — source d'artefacts d'AMORÇAGE, intrant // `artefacts_amorcage`. Remplacé par `client_artefacts` (00-setops-artefacts, // qui trie après) dès que l'écosystème a sa propre source. // // UNE ADRESSE, JAMAIS UN NOM : au moment où ce fichier sert, la machine n'a pas // encore de résolveur, et le DNS sortant d'un tenant est fermé par conception. Acquire::http::Proxy "http://{{ artefacts_amorcage }}"; // `DIRECT` est obligatoire : apt fait HÉRITER la valeur HTTPS de la valeur HTTP // quand elle n'est pas définie, et enverrait les dépôts tiers en HTTPS dans un // cache qui refuse les tunnels (mesuré le 2026-08-23). Acquire::https::Proxy "DIRECT"; when: - artefacts_amorcage is defined - artefacts_amorcage | string | length > 0 - name: Lire le résolveur en place ansible.builtin.slurp: src: /etc/resolv.conf register: serveur_debian_resolv_actuel failed_when: false changed_when: false - name: Poser le résolveur d'amorçage (avant tout apt) ansible.builtin.copy: dest: /etc/resolv.conf owner: root group: root mode: "0644" content: | # Géré par Set-OPS — résolveur d'amorçage (intrant `dns_amorcage`). # Remplacé par `client_resolveur` lorsqu'il bascule vers le résolveur local. {% for serveur in dns_amorcage.split(',') if serveur | trim %} nameserver {{ serveur | trim }} {% endfor %} # L'AMORÇAGE NE DOIT PAS DÉFAIRE CE QUI EST DÉJÀ EN PLACE (2026-08-25). # # La garde ne protégeait que l'hôte du résolveur lui-même (`127.0.0.1`). Partout # ailleurs, le socle réécrivait `/etc/resolv.conf` avec `dns_amorcage` — donc # **défaisait la bascule** de `client_resolveur` à chaque passage. # # Ça ne s'était jamais vu chez un tenant : `dns_amorcage` y vaut l'adresse du # résolveur du tenant, si bien que réécrire remettait la même valeur. La # coïncidence masquait le défaut. # # Sur le site, les deux ont divergé quelques heures — l'amorçage pointait encore sur # la frontière alors que `client_resolveur` avait basculé les machines sur # `site-dns-01`. Chaque déploiement du socle les ramenait en arrière, en silence, et # ça ne s'est vu qu'en retirant la règle de pare-feu vers la frontière : les cinq # machines ont alors perdu la résolution d'un coup. # # On ne pose donc l'amorçage que si rien de sensé n'est déjà là : ni la loopback, ni # un résolveur déclaré de cet écosystème. vars: serveur_debian_resolv_texte: >- {{ serveur_debian_resolv_actuel.content | default('') | b64decode | string }} serveur_debian_resolveurs_declares: >- {{ (groups['serveur_resolveur'] | default([])) | map('extract', hostvars, 'ansible_host') | select | list }} when: - dns_amorcage is defined - dns_amorcage | string | length > 0 - "'127.0.0.1' not in serveur_debian_resolv_texte" - serveur_debian_resolveurs_declares | select('in', serveur_debian_resolv_texte) | list | length == 0 roles: # LE PLANCHER AVANT LE PREMIER `apt` (2026-08-25). # # `hosts_statiques` venait APRÈS `common_packages`, qui commence par un `apt update`. # Or apt vise le cache PAR SON NOM — `site-cache-01.` — ce qui est voulu : # une configuration agnostique de l'adressage. # # Le jour où les adresses changent, la boucle se referme : apt échoue faute de # résoudre, donc le socle n'atteint jamais `hosts_statiques`, donc le plancher reste # périmé, donc apt échoue. Mesuré le 2026-08-25 après le découpage du site en zones : # cinq machines bloquées, `/etc/hosts` vide de toute entrée du site. # # Le résolveur d'amorçage est déjà une `pre_task` pour exactement cette raison. Le # plancher est de la même nature : il ne s'installe pas, **il rend installable**. - hosts_statiques - common_packages - qemu_guest_agent - cloud_init - sudo_ansible - chrony - ssh_baseline - systemd_ssh_auto - motd