Set-OPS-Public/playbooks/groupes/serveur_debian.yml
Daniel Allaire 1a7c042e5b site : quatre zones d'autorite, et l'ordre inscrit dans les integrations
Le site n'est plus un /24 plat. Une zone par nature d'autorite — pilotage, autorite,
genome, service — chacune son VLAN et sa patte sur la frontiere. L'inversion corrigee,
mesuree : les cinq VM du site n'avaient AUCUN filtrage est-ouest, contre policy_in=DROP
sur une machine de tenant. La plus autoritaire etait la moins protegee.

Filtrage nord-sud par choix de l'exploitant : un seul point de police, un seul devis.
90 -> 117 regles. Chaque flux `flotte` produit une regle par zone SOURCE, destination
nommee — ce qui etait gratuit devient police.

L'ORDRE FAIT PARTIE DE L'INTEGRATION. client_pki tournait en parallele sur tous les hotes ;
sur celui qui porte l'autorite il recharge step-ca, et les quatre autres echouaient dans
cette fenetre sur `TLS handshake timeout` — un message qui accuse le reseau. Chaque
integration declare desormais sa dependance dans meta/integration.yml, les playbooks en
sont le miroir genere, et P44 refuse l'ecart (4 controles negatifs). `serveur: ~` est une
reponse valable : client_metrique pose un exportateur qu'on vient LIRE.

Autres defauts du meme soir :
  - le plancher /etc/hosts venait APRES le premier apt, qui vise le cache par son NOM :
    boucle fermee des que les adresses changent. Il ne s'installe pas, il rend installable.
  - dns_amorcage ecrit en dur a eu tort deux fois ; il se derive de serveur_resolveur.
  - l'ACL du resolveur derivait d'un seul sous-reseau : trois zones refusees sur quatre.

ET UNE ERREUR A MOI : j'ai diagnostique un trou noir de MTU et declare 1450. Faux — pas de
VXLAN sur ce chemin, tout est a 1500 de bout en bout. Ma mesure etait reelle, mon
interpretation non : je venais de debrancher la carte a chaud, et chaque `ip link set mtu`
reconfigurait l'interface. C'est la reconfiguration qui debloquait, pas la valeur.

44 preuves vertes, ansible-lint profil production.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-25 17:31:07 -04:00

102 lines
4.7 KiB
YAML

---
- 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.
- 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.<domaine>` — 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