Le port du commutateur vers la frontière était figé sur le seul VLAN de transit. Depuis que les bifrost ont une patte sur le VLAN de sortie tenant, ce port serait resté muet : le devis aurait eu l'air juste et le trafic ne serait jamais arrivé. Il dérive maintenant des rattachements déclarés des hôtes `role: frontiere`. Contexte, côté underlay (dépôt de l'hébergeur) : le VTEP vivait sur le VLAN 10, donc le transport tenant partageait son domaine de diffusion avec l'administration des équipements. Plus grave, un nœud de sortie décapsule le trafic tenant et le remet dans sa table principale — dont la route par défaut sort par vmbr0, l'interface de gestion des nœuds. D'où deux VLAN dédiés, 11 (transport VXLAN) et 41 (trafic décapsulé). Le second n'a volontairement pas de passerelle : le commutateur le transporte sans le router, et le devis n'émet donc pas d'interface Vlan41. Services de l'hébergeur — décision consignée, rien n'est construit : Aucun équipement de l'hébergeur n'est dans un inventaire Ansible, et rien ne sauvegarde leurs configurations. Ni hyperviseurs, ni commutateurs, ni frontière. D-46 : un hébergeur porte trois catégories — son tenant (un client comme les autres), ses opérations (supervision de la fabric, journaux, sauvegarde des configs, DNS d'underlay), et le plan de contrôle (déjà dehors). D-47 : les opérations vivent dans le dépôt de l'hébergeur, et leurs VM se rattachent à un pont VLAN, jamais un VNet. Un service qui observe la fabric ne peut pas dépendre d'elle : l'EVPN tombe, et la supervision tombe avec la raison de la panne. D-48 : les hyperviseurs sont gérables par Ansible ; « hors flotte » ne vaut que pour les commutateurs (aucun agent) et la frontière (API seulement). Question laissée ouverte : l'index 0 réservé au tenant propre de l'hébergeur. Il produit les VNI 1001-1006, que le parc hérité utilise déjà (1001 TechnoLibre historique, 1003 KBR), et P21 déclencherait une fausse collision entre deux dépôts d'hébergeurs. Construction parallèle vérifiée : aucune collision entre les 38 VM héritées et les VNI/VLAN projetés. 30 preuves OK. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
9.2 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 |
| Décisions d'architecture | docs/decisions-architecture.md — 28 décisions, pourquoi, où lire le détail, et ce qui les garde ; plus les décisions renversées et leur cause |
| SDN / routage | docs/sdn-evpn.md — décision du 2026-08-02 : le routage inter-zone passe des commutateurs aux hyperviseurs (zones EVPN = VRF). Non éprouvé : spike avant génération |
| Migration de tenant | docs/migration-tenant.md — recette en 8 étapes, machine à états, gardes ; le receveur se construit avant tout gel |
| 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 |
| Exploitation de l'hébergeur | ses opérations (supervision de la fabric, sauvegarde des configs, DNS d'underlay) n'appartiennent à aucun tenant et restent hors overlay | décidé, non construit : aucun équipement d'hébergeur n'est encore dans un inventaire | hebergeur-exploitation.md |
| Authentification | web → Keycloak ; LDAP source unique ; secours par sudo, formulaire local non annoncé |
<rôle>_connexion_locale: false (grafana, forgejo, nextcloud) ; garde de version Forgejo ≥ 10 |
authentification.md |
| SDN EVPN | ajouter un tenant implique 1 zone + 6 VNets + 6 sous-réseaux, tous dérivés du seed | scripts/devis_sdn.py (make devis-sdn) ; nommage dérivé du tenant (CHEZ17, chez174), ≤ 8 caractères ; garde P30 |
sdn-evpn.md §2 |
| Pools Proxmox | un pool par tenant : les noms courts de VM sont volontairement identiques d'un tenant à l'autre (même fonction, même nom), et seule la console Proxmox en souffrait | scripts/devis_proxmox_pools.py (make devis-proxmox-pools) ; nom dérivé de l'index ; garde de collision = preuve P28 |
decisions-architecture.md D-37 |
| 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.