La bordure devient un artefact dérivé, comme le devis switch — et le chemin
qui y mène est enfin déclaré.
`make devis-opnsense` (+ preuve P24) dérive la politique de bordure du
registre des flux : les flux `pair: externe`, que `resoudre_flux.py` saute
volontairement parce qu'ils relèvent de la frontière et non du pare-feu
d'hôte. Aucun port, aucune adresse, aucun nom d'hôte dans le générateur.
Le lien manquait dans tous les fichiers : le devis switch ne contenait pas
une seule `ip route`. Un réseau underlay portant `passerelle_sortie` le
déclare — il vit dans l'underlay et non dans un tenant parce que la
frontière route vers TOUS les supernets tenants par le même saut, donc il
ne peut dériver d'aucun `index`. `devis-reseau` en tire deux routes :
l'aller (sortie générale) et le retour vers l'administration, dont l'absence
a coûté la passe de déploiement du 2026-07-29 — la réponse revient au
pare-feu par une autre interface que celle où l'état a été créé, et se fait
jeter en silence.
Les réseaux d'administration viennent de l'intrant `nftables_admin_ssh` :
même source unique que la garde anti-lockout des nftables et l'alias
SETOPS_ADMIN. Les trois pare-feux et les routes ne peuvent plus diverger.
La frontière est réglable depuis la console (section « Frontière » du
panneau Intrants) ; les identifiants d'API restent interdits d'écriture par
le GUI et vivent dans la voûte.
Correctifs de la même passe :
- le panneau refusait d'enregistrer les intrants de la frontière : le
garde-fou confondait une référence de voûte `{{ vault_* }}` préservée
avec un secret soumis. Il regarde désormais la valeur, pas le nom.
- `supprimer_vm_debian.yml` ne chargeait que `proxmox.vault.yml` pour ses
secrets ; retirer ce reliquat aurait cassé `make detruire`. Aligné sur le
playbook de clonage, voûte unique en dernier.
- documentation : la voûte est unique, `proxmox.vault.yml` n'est qu'un
reliquat de compatibilité.
Preuves : 24 OK, 0 échec. Cas de rejet du validateur d'underlay exercés un
par un ; résolution du jeton Proxmox vérifiée en exécution réelle.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
7.6 KiB
Carte d'orientation Set-OPS
À lire en premier. Point d'entrée vers le corpus documentaire, et catalogue des mécanismes transverses — ceux qui vivent dans le code et qu'on re-découvre sinon. Créée le 2026-07-03 après un audit du dépôt, revue le 2026-07-29. But : ne plus re-déterrer ce qui existe.
Le dépôt est déjà bien documenté (26 docs + 7 pièces d'audit + 21 unités de wiki, et un README par rôle). Le manque n'était pas la doc du modèle, mais (a) un index « par où commencer » et (b) une carte des mécanismes (dispersés dans le code + les README de rôles). Cette page comble ces deux trous.
1. À lire d'abord (dans l'ordre)
| Sujet | Documents |
|---|---|
| Autorité / gouvernance | AGENTS.md (source d'autorité), CLAUDE.md, docs/MISE-A-JOUR-CODEX-CLAUDE.md |
| Le modèle (plan) | docs/architecture-set-ops.md (survol) → docs/plan-et-generation.md (à fond) → docs/meta-classe.md (concept) |
| Services, maturité, dette | docs/catalogue-services.md (la carte de maturité + la cruft y sont déjà) |
| Exploitation / VM | docs/vm-lifecycle.md, docs/procedure-template-debian13-proxmox.md, docs/config-proxmox.md, docs/nomenclature-vm.md, docs/multi-instances.md |
| Conceptions de domaine | docs/identite-sso.md, docs/courriel-conception.md, docs/bindings-conception.md, docs/dns-interne.md, docs/dimensionnement-ressources.md, docs/integrations-vm.md |
| Réseau / pare-feu | docs/flux-conception.md (le modèle) → docs/registre-flux.md (généré, matrice d'audit) → docs/frontiere-opnsense.md (la bordure nord/sud) ; underlay : underlay.yml.example + make underlay |
| Ordre de déploiement | docs/couches-deploiement.yml (couches) + docs/dependances-groupes.yml (graphe) → playbooks/site.yml (généré, make site) |
| Preuve / recette | docs/audit/affirmations.md (registre), make prouver → docs/audit/preuve-<date>.md, docs/audit/plan-de-recette.md (généré du wiki), docs/audit/protocole-operateur-independant.md |
| Exploitation courante | docs/runbooks-exploitation.md, docs/intrants-communs.md, docs/intrants-base-gui-conception.md, docs/theme-forgejo-hors-flotte.md |
| Pédagogie (le wiki) | wiki/ — 21 unités (+ _Sidebar) publiées par make wiki-publier ; entrer par wiki/Home.md |
| Vision / positionnement | docs/ecosysteme-chezlepro.md, docs/positionnement.md, docs/pouvoirs-set-ops.md |
2. Les mécanismes transverses (et OÙ ils vivent)
Ce que je re-découvre sinon. Consulter avant de concevoir un nouveau mécanisme.
| Mécanisme | Ce que c'est | Où, dans le code | Doc |
|---|---|---|---|
| Plan → inventaire | plan/*.yml → hosts.yml généré |
scripts/instancier.py, scripts/inventory_rules.py |
plan-et-generation.md |
| Nomenclature dérivée | VMID / IP / VLAN / FQDN dérivés | inventory_rules.deriver_nomenclature + plan/nomenclature.yml |
nomenclature-vm.md |
| Dimensionnement | RAM/CPU/disque sommés par logiciel | roles/*/meta/empreinte.yml → deriver_ressources |
dimensionnement-ressources.md |
| Bindings app→app | lien côté app (liens) résolu en host_vars |
plan/applications.yml liens: + roles/*/meta/liens.yml + instancier.resoudre_liens |
bindings-conception.md |
| Bindings app→base | lien côté base (consommateur/portee) résolu dans le rôle |
plan/bases-donnees.yml + rôle utilitaire resoudre_base (lookup('vars', secret), no_log) inclus par le consommateur |
bindings-conception.md §5 |
| Résolution d'annuaire | connexion LDAP (uri/base DN/bind) dérivée, jamais recopiée | rôle utilitaire resoudre_annuaire (inclus par dovecot/postfix/keycloak/icingaweb2) |
identite-sso.md |
| Plancher de résolution | /etc/hosts généré depuis l'inventaire + alias d'expose → l'écosystème se résout DNS éteint |
rôle hosts_statiques (appliqué dans la couche socle) |
dns-interne.md |
| Pont de certificat | cert step_ca → service, resync au renouvellement | script *-cert-sync + unité .path, dans chaque rôle serveur ; cert déposé par client_pki |
— |
| Ordonnancement socle-first | socle/durci avant les client_* |
serveur_debian/serveur_durci d'abord (posent /etc/hosts via hosts_statiques) |
— |
| Sûreté check-mode | dry-run fiable | when: not ansible_check_mode sur les tâches de service + handlers |
— |
| Voûte au déploiement | secret jamais en clair | ANSIBLE_VAULT_PASSWORD_FILE / ~/.config/setops-vault-pass ; déréférencé par lookup('vars', <nom>) |
— |
| Multi-instance | un dépôt par écosystème ; l'active = symlink instance/, les autres découvertes par convention (dossiers frères, aucun registre) |
active : symlink instance/ ; découverte : scripts/instances.py / devis_reseau.py (glob ../*/plan/nomenclature.yml avec index) ; garde-fou collision : preuve P21 |
multi-instances.md |
| Exposition → edge | app expose un FQDN public servi par un edge | plan/domaines.yml + expose (applications) |
bindings-conception.md §4 |
| Frontière nord/sud | les flux pair: externe — sautés par le pare-feu d'hôte — sont la politique de bordure |
scripts/devis_opnsense.py (make devis-opnsense) ; garde d'accès admin = preuve P24 |
frontiere-opnsense.md |
⚠️ Deux directions de binding, assumées :
app→appcôté app (instancier),app→basecôté base (registre, résolu en rôle pour que le secret ne quitte jamais le rôle). Ne pas unifier l'un dans l'autre sans raison. Cf.bindings-conception.md.
3. Maturité & dette
- Maturité des rôles, échafaudages, rôles-catégories inertes : voir
docs/catalogue-services.md« État d'implémentation » (source de vérité, tenue à jour). - Dette (audit 2026-07-03, revu le 2026-07-29) :
- ✅ soldé — README de rôles : tous les rôles en ont un (les 12 manquants écrits le
2026-07-29 :
serveur_debian,hosts_statiques,resoudre_base,resoudre_annuaire,serveur_dovecot,serveur_postfix,serveur_rspamd,client_backup,serveur_backup,client_unbound,serveur_oauth2_proxy,serveur_icingaweb2). - ✅ soldé —
exposeest consommé au déploiement :plan/applications.yml→ filtreexpositions_des_applications→ vhosts nginx dérivés (roles/serveur_nginx/tasks/main.yml, templateexpositions.conf.j2, drapeauserveur_nginx_publier_expositions), + alias/etc/hostsposés parhosts_statiques,- SANs des certificats d'edge dérivés par
scripts/instancier.py.
- SANs des certificats d'edge dérivés par
- ⏳ ouvert —
meta/liens.ymlseulement surserveur_postfix(mailstore,milter) : les autres liens app→app viendront. - ⏳ ouvert —
requiert: câblé côté GUI (édition + validationvalider_applications) mais pas consommé au déploiement ; c'est un indice de dépendance applicative. Les dépendances de groupes (celles qui pilotent l'ordre) vivent dansdocs/dependances-groupes.yml+docs/couches-deploiement.yml, et sont bel et bien consommées par l'orchestrateur (scripts/orchestrer.py→playbooks/site.yml).
- ✅ soldé — README de rôles : tous les rôles en ont un (les 12 manquants écrits le
2026-07-29 :
4. Discipline (pour ne plus re-déterrer)
Avant de concevoir ou d'ajouter un mécanisme :
- lire cette carte + le doc du sujet ;
- arpenter le code (
grep) et lire les README des rôles concernés ; - étendre / factoriser l'existant plutôt qu'ajouter un chemin parallèle.
Un seul agent IA travaille dans le dépôt à la fois (Codex ou Claude) — cf. AGENTS.md.