2026-06-30 10:07:17 -04:00
|
|
|
# Intrants communs de l'écosystème
|
|
|
|
|
|
preuve : P34 — chaque document declare son lecteur (D-74)
La refonte de ce matin posait une convention. Une convention qu'on n'outille
pas tient tant que quelqu'un y pense : c'est le raisonnement de D-70, applique
au corpus documentaire.
Etat de depart mesure : 2 documents sur 34 declaraient leur lecteur. Les 32
autres disaient leur SUJET — ce qui avait enfoui le runbook de reprise le plus
utile du depot au §6 de autorisation.md.
Les 38 le declarent desormais, lecteur determine document par document et non
colle au gabarit : l'exploitant (devis, migration de tenant, cycle de vie,
gabarit d'or), le mainteneur (conceptions, registres, carte), le lecteur
externe (ecosysteme-chezlepro), l'agent IA (MISE-A-JOUR-CODEX-CLAUDE).
Deux exemptions DERIVEES, pas listees — un chemin en dur aurait vieilli a la
premiere page ajoutee : un document qui s'annonce genere, et un fragment sans
titre. Les 13 exemptes verifies un par un ; aucun document ecrit a la main
n'est exempte par accident. La preuve ne lit que l'EN-TETE, ce qui empeche
frontiere-opnsense.md et plan-et-generation.md — qui parlent de generation
dans leur corps — d'etre exemptes a tort.
Eprouvee dans les deux sens. Elle a echoue seule des sa premiere execution en
nommant deux documents que mon inventaire avait manques (docs/audit/). Puis
test negatif delibere : declaration retiree de meta-classe.md -> ECHEC la
nommant ; restauree -> OK.
Ce qu'elle ne teste pas : que le lecteur declare soit le BON. Ca se juge en
revue ; elle garantit qu'on a du y penser.
P01–P34. Comptes perimes corriges au passage (AGENTS.md et devis-services.md
annoncaient encore 30 preuves).
Verifie : prouver.py 0 (34 OK), plan-recette inchange.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-10 07:53:04 -04:00
|
|
|
> **Pour qui :** le **mainteneur** — les valeurs partagées par tout l'écosystème, et qui les possède.
|
|
|
|
|
|
2026-06-30 10:07:17 -04:00
|
|
|
Recensement des **intrants communs** : les valeurs partagées par tout l'écosystème
|
|
|
|
|
(par opposition aux valeurs propres à un seul hôte). Objectif : les saisir **une
|
|
|
|
|
fois**, depuis un endroit unique, puis les laisser se **dériver** ou se **propager**.
|
|
|
|
|
|
|
|
|
|
> Concept lié : [`meta-classe.md`](meta-classe.md) (une définition instancie la flotte)
|
|
|
|
|
> et [`dimensionnement-ressources.md`](dimensionnement-ressources.md).
|
|
|
|
|
|
|
|
|
|
## 1. Recensement par domaine
|
|
|
|
|
|
|
|
|
|
### A. Identité de l'instance — `group_vars/<env>/all.yml`
|
|
|
|
|
- **`domaine_interne`** — domaine DNS interne (ex. `chezlepro.internal`). **Keystone** :
|
|
|
|
|
zones DNS, FQDN, base DN LDAP, expéditeurs courriel, URL AC en dérivent.
|
2026-07-05 00:47:44 -04:00
|
|
|
- `fuseau_horaire` — fuseau (ex. `America/Toronto`).
|
2026-06-30 10:07:17 -04:00
|
|
|
- `setops_plan_dir` — chemin du plan.
|
|
|
|
|
|
|
|
|
|
### B. Réseau & nomenclature — `plan/nomenclature.yml`
|
|
|
|
|
- `supernet`, `cidr_hote`, `reservations`, `categories` (VLAN/sous-réseau/passerelle),
|
|
|
|
|
`fonctions` (catégorie + service).
|
|
|
|
|
|
frontière nord/sud : devis dérivé, lien de transit et les deux routes
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>
2026-08-01 19:32:04 -04:00
|
|
|
### C. Hyperviseur Proxmox — `group_vars/proxmox.yml`
|
2026-06-30 10:07:17 -04:00
|
|
|
- `proxmox_api_host`, `proxmox_api_user`, `proxmox_api_port`, `proxmox_validate_certs`.
|
frontière nord/sud : devis dérivé, lien de transit et les deux routes
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>
2026-08-01 19:32:04 -04:00
|
|
|
- 🔒 `proxmox_api_token_id`, `proxmox_api_token_secret` — dans la **voûte unique** de
|
|
|
|
|
l'instance, `group_vars/all/vault.yml`. (L'ancienne `proxmox.vault.yml` reste lue en
|
|
|
|
|
compatibilité si elle existe encore ; cf. `docs/config-proxmox.md`.)
|
2026-06-30 10:07:17 -04:00
|
|
|
- Golden template : `proxmox_clone_vmid_modele`, `proxmox_clone_source_nom`.
|
|
|
|
|
- Placement par défaut : `proxmox_clone_noeud`, `proxmox_clone_stockage`,
|
|
|
|
|
`proxmox_clone_pont`, format, complet, timeout, disque, interface, démarrer.
|
|
|
|
|
|
|
|
|
|
### D. Identité initiale des VM — `group_vars/modeles_vm.yml`, `creer-vm`
|
|
|
|
|
- **Clé publique SSH** (cloud-init) — accès admin de toute la flotte.
|
|
|
|
|
- Compte technique `ansible` (`sudo_ansible_admin_user`) + sudo NOPASSWD, `ciuser`.
|
|
|
|
|
- Politiques SSH communes (port, password auth off, root login off, grace/auth tries).
|
|
|
|
|
|
|
|
|
|
### E. Socle durci commun — `group_vars/modeles_vm.yml`
|
|
|
|
|
nftables baseline · fail2ban SSH · auditd · AppArmor · sysctl · unattended-upgrades ·
|
|
|
|
|
journald (rétention) · core_dumps · systemd_ssh_auto.
|
|
|
|
|
|
|
|
|
|
### F. Endpoints des services centraux (les rôles `client_*` en dérivent)
|
Retirer 3 rôles legacy (serveur_sendmail, client_dns, client_ldap) + nettoyage
Supprimés (supersédés / hors-conception) : serveur_sendmail (→ Postfix),
client_dns (→ plancher + client_unbound), client_ldap (login LDAP OS, hors
design). Rôles + playbooks de groupe retirés.
Nettoyage des références :
- dependances-groupes.yml : entrées client_dns/client_ldap retirées + entrées
mortes des scaffoldings (nextcloud/collabora/client_supervision) ; deps
périmées corrigées (client_smtp → serveur_postfix ; serveur_keycloak →
serveur_postgresql, la raison parlait à tort de Nextcloud).
- 6 modèles d'exemple : app mail serveur_sendmail → serveur_postfix.
- README, AGENTS : listes/glossaire nettoyés.
- catalogue-services : listes, tables, roadmap ; note « rôles retirés ».
- nomenclature-vm : infra-mail-01 → serveur_dovecot (était faux).
- courriel-conception, dns-interne (re-ciblé client_unbound), pouvoirs,
intrants, READMEs (client_smtp/forgejo/openldap/unbound).
ansible-lint : 0 échec (366 fichiers). instancier OK.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-04 12:14:04 -04:00
|
|
|
- DNS interne : plancher `/etc/hosts` (`hosts_statiques`) + PowerDNS + `client_unbound` (opt-in).
|
2026-06-30 10:07:17 -04:00
|
|
|
- AC/PKI (`client_pki_ca_url` → infra-pki, provisioner).
|
Retirer 3 rôles legacy (serveur_sendmail, client_dns, client_ldap) + nettoyage
Supprimés (supersédés / hors-conception) : serveur_sendmail (→ Postfix),
client_dns (→ plancher + client_unbound), client_ldap (login LDAP OS, hors
design). Rôles + playbooks de groupe retirés.
Nettoyage des références :
- dependances-groupes.yml : entrées client_dns/client_ldap retirées + entrées
mortes des scaffoldings (nextcloud/collabora/client_supervision) ; deps
périmées corrigées (client_smtp → serveur_postfix ; serveur_keycloak →
serveur_postgresql, la raison parlait à tort de Nextcloud).
- 6 modèles d'exemple : app mail serveur_sendmail → serveur_postfix.
- README, AGENTS : listes/glossaire nettoyés.
- catalogue-services : listes, tables, roadmap ; note « rôles retirés ».
- nomenclature-vm : infra-mail-01 → serveur_dovecot (était faux).
- courriel-conception, dns-interne (re-ciblé client_unbound), pouvoirs,
intrants, READMEs (client_smtp/forgejo/openldap/unbound).
ansible-lint : 0 échec (366 fichiers). instancier OK.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-04 12:14:04 -04:00
|
|
|
- IdM/LDAP : annuaire résolu par `resoudre_annuaire` (hôte + base DN dérivés du domaine).
|
|
|
|
|
- Relais courriel (`client_smtp_relais` → edge-mta, MTA Postfix, port 25).
|
2026-06-30 10:07:17 -04:00
|
|
|
- Métriques (node_exporter `:9100`).
|
|
|
|
|
- Journaux (`client_journal_loki_url` → obs).
|
|
|
|
|
- Temps (NTP) : **implicite** (pool Debian par défaut — aucun intrant configuré).
|
|
|
|
|
|
|
|
|
|
### G. Dépôts APT tiers communs
|
|
|
|
|
- Smallstep (step-cli) — `client_pki` ↔ `serveur_step_ca`.
|
|
|
|
|
- Grafana (alloy/loki/grafana) — `client_journal` ↔ `serveur_loki`/`serveur_grafana`.
|
|
|
|
|
|
2026-06-30 15:42:12 -04:00
|
|
|
### H. Secrets Vault communs 🔒 — **voûte unique** `group_vars/all/vault.yml`
|
|
|
|
|
> Tous les secrets de l'instance dans **un seul fichier chiffré par environnement**
|
|
|
|
|
> (`inventories/<env>/group_vars/all/vault.yml`), gabarit
|
|
|
|
|
> [`exemples/vault.exemple.yml`](../exemples/vault.exemple.yml). Un mot de passe, un
|
|
|
|
|
> endroit. Édité via `ansible-vault edit` (jamais par le GUI).
|
2026-08-01 22:37:27 -04:00
|
|
|
**La liste ne s'écrit pas ici.** Elle se *recense*, depuis le plan, les rôles des groupes
|
|
|
|
|
actifs et les `group_vars` :
|
|
|
|
|
|
|
|
|
|
```sh
|
|
|
|
|
python3 scripts/voute.py lister # chaque secret exigé + d'où vient l'exigence
|
|
|
|
|
make prouver # P18 : le gabarit les couvre-t-il tous ?
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
C'est la même source que le rappel « Secrets attendus » du panneau d'intrants. Trois copies
|
|
|
|
|
manuelles de cette liste ont existé et **toutes ont divergé** — elles annonçaient
|
|
|
|
|
`vault_ldap_sssd`, qu'aucun rôle ne consomme, et `vault_step_ca_fingerprint`, que
|
|
|
|
|
`client_pki` dérive à chaud depuis l'AC plutôt que de la lire.
|
|
|
|
|
|
2026-06-30 10:07:17 -04:00
|
|
|
Mot de passe du Vault lui-même : saisi au déploiement.
|
|
|
|
|
|
|
|
|
|
### I. Exposition publique — `plan/domaines.yml`
|
|
|
|
|
domaines publics, `edge`, autorité DNS, FQDN exposés.
|
|
|
|
|
|
|
|
|
|
## 2. Classification proposée : constante vs défaut surchargeable
|
|
|
|
|
|
|
|
|
|
> **Proposition à valider.** « Constante » = une seule valeur, pas de surcharge
|
|
|
|
|
> (diverger casserait le modèle). « Défaut surchargeable » = valeur globale qui
|
|
|
|
|
> ressurgit comme défaut là où l'intrant réapparaît (hôte / groupe / application).
|
|
|
|
|
|
|
|
|
|
| Intrant | Classe | Surcharge où ? |
|
|
|
|
|
| --- | --- | --- |
|
|
|
|
|
| `domaine_interne` | **Constante** | — |
|
|
|
|
|
| Nomenclature (supernet, CIDR, catégories, fonctions) | **Constante** | — (le plan réseau est la loi) |
|
|
|
|
|
| Accès Proxmox (API host/user/port/token) | **Constante** | — (un seul cluster) |
|
|
|
|
|
| Golden template (vmid_modele, source_nom) | **Constante** | — |
|
|
|
|
|
| Secrets Vault | **Constante** 🔒 | — (gérés à part, jamais en clair) |
|
2026-07-05 00:47:44 -04:00
|
|
|
| `fuseau_horaire` | Défaut | par hôte (rare) |
|
2026-06-30 10:07:17 -04:00
|
|
|
| `proxmox_clone_noeud` / `stockage` / `pont` | Défaut | par hôte (`serveurs.yml`) |
|
Retirer 3 rôles legacy (serveur_sendmail, client_dns, client_ldap) + nettoyage
Supprimés (supersédés / hors-conception) : serveur_sendmail (→ Postfix),
client_dns (→ plancher + client_unbound), client_ldap (login LDAP OS, hors
design). Rôles + playbooks de groupe retirés.
Nettoyage des références :
- dependances-groupes.yml : entrées client_dns/client_ldap retirées + entrées
mortes des scaffoldings (nextcloud/collabora/client_supervision) ; deps
périmées corrigées (client_smtp → serveur_postfix ; serveur_keycloak →
serveur_postgresql, la raison parlait à tort de Nextcloud).
- 6 modèles d'exemple : app mail serveur_sendmail → serveur_postfix.
- README, AGENTS : listes/glossaire nettoyés.
- catalogue-services : listes, tables, roadmap ; note « rôles retirés ».
- nomenclature-vm : infra-mail-01 → serveur_dovecot (était faux).
- courriel-conception, dns-interne (re-ciblé client_unbound), pouvoirs,
intrants, READMEs (client_smtp/forgejo/openldap/unbound).
ansible-lint : 0 échec (366 fichiers). instancier OK.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-04 12:14:04 -04:00
|
|
|
| DNS internes (plancher `/etc/hosts` + PowerDNS + `client_unbound`) | Défaut | par hôte / groupe |
|
2026-06-30 10:07:17 -04:00
|
|
|
| Politiques durcissement (SSH, nftables, fail2ban, journald…) | Défaut | par hôte / groupe |
|
|
|
|
|
| Relais SMTP, TLS internes | Défaut | par hôte / groupe |
|
|
|
|
|
| `ciuser`, compte `ansible` | Défaut | rarement surchargé |
|
|
|
|
|
|
|
|
|
|
## 3. Saisie unique dans le GUI (cible)
|
|
|
|
|
|
|
|
|
|
Un panneau « Intrants de base » dans le GUI :
|
|
|
|
|
- édite les **constantes** et les **défauts** au même endroit ;
|
|
|
|
|
- pour un **défaut**, la valeur globale apparaît pré-remplie (et signalée comme
|
|
|
|
|
« héritée ») là où l'intrant réapparaît dans le plan, surchargeable sur place ;
|
|
|
|
|
- les **secrets** ne sont **jamais** stockés en clair par le GUI (cf. §H) — il en
|
|
|
|
|
gère au plus les *références*, l'édition réelle restant côté Vault.
|
|
|
|
|
|
Mise en conformité prouvable : registre d'affirmations + make prouver
Le dépôt fait / explique / prouve ce qu'il affirme, vérifiable en une commande.
- Phase 1 : docs/audit/affirmations.md — 54 affirmations publiques tracées vers
une commande de preuve et un statut (✅/🟡/❌/⚪).
- Phase 2 : CLAUDE.md réduit à un pointeur mince ; contradiction SSH levée (le
code applique déjà PasswordAuthentication no + AuthenticationMethods publickey,
conforme à AGENTS.md) ; section AGENTS « Codex » → « agents IA ».
- Phase 3 : parcours démarrage réparé (QUICKSTART renvoyait à un modèle absent,
chemins de voûte faux, commandes make périmées) ; make verifier vert
(ansible-lint 33 → 0 : site.yml généré nommé, pipefail, name[template]) ;
voûte Proxmox unifiée lue par le clonage (all/vault.yml).
- Phase 4 : make prouver → docs/audit/preuve-<date>.md, harnais rejouable qui
rappelle l'outillage existant (aucune validation réimplémentée).
- Phase 5 : parcours QUICKSTART prouvé hors-ligne sur le socle ; modèle socle
rendu valide (autorite interne → auto-heberge) ; split-brain d'inventaire
corrigé (repli sur le répertoire existant, pas principal/).
make prouver : 15 OK, 0 échec, 1 sautée (voûte). ansible-lint : 0 failure.
Écarts découverts en cours de traitement (AFF-097..100) : tous résolus.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-20 19:53:18 -04:00
|
|
|
Persistance : les fichiers de l'instance (`group_vars/all/10-intrants.yml` — forme
|
|
|
|
|
dossier ; la forme plate `group_vars/all.yml` reste lue en compatibilité —, `proxmox.yml`,
|
|
|
|
|
`modeles_vm.yml`, `plan/nomenclature.yml`). À détailler dans la note de conception de la
|
|
|
|
|
fonctionnalité GUI.
|
2026-06-30 10:07:17 -04:00
|
|
|
|
|
|
|
|
## 4. Incohérences repérées (à corriger)
|
2026-07-05 00:47:44 -04:00
|
|
|
- `fuseau_horaire` défini en **lab** seulement, absent de **production**.
|
2026-06-30 10:07:17 -04:00
|
|
|
- `group_vars/serveur_debian.yml` **référencé** (commentaire de prod `all.yml`) mais
|
|
|
|
|
**absent** des deux environnements.
|