Suppression de toute trace Chezlepro de l'outil (roles, scripts, docs publiques, exemples, LICENSE). Prouve par scan exhaustif : git grep vide pour chezlepro, asgard/TrueNAS, supernet reel 10.1.x. Corrige 5 defauts de genericite fonctionnels (motd, app.ini Forgejo, organisation openldap, nom AC step-ca, et IP reelles codees en dur dans les defaults de roles -> plage d'exemple 10.0.x). LICENSE -> Alliance Boreale. Fichiers mainteneur + CHANGELOG conserves (par decision). La separation moteur/instance tient : OPS-Chezlepro surcharge deja ses vraies valeurs de topologie. Verifie : make verifier exit 0 (4 tests). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
8.3 KiB
Le plan et la génération d'inventaire (méta-classe)
Set-OPS ne s'édite plus comme un inventaire à la main : on décrit un plan, et l'inventaire Ansible en est généré. Le dépôt est la définition ; chaque VM en est une instance. Ce document décrit le modèle, les registres, les commandes et le flux de travail.
Règle d'or :
instance/inventories/production/hosts.ymlest GÉNÉRÉ. Ne jamais l'éditer à la main. On édite le plan puis on régénère (make instancier-appliquer).
1. Le modèle : deux ancres, cinq liens
L'écosystème = des serveurs (VM) et des applications, reliés à leurs bases, leurs domaines et leurs dépendances :
serveur (VM) ──fournit──▶ capacités (= groupes/rôles Ansible)
application ──tourne_sur──▶ serveur (une VM peut porter N applications)
application ──requiert──▶ application(s) (DNS, PKI, BD…)
application ──utilise──▶ base(s) (via le DSN)
application ──expose──▶ domaine(s) public(s) (le FQDN, derrière l'edge)
base ──hébergée_sur──▶ serveur de BD
L'application est l'entité pivot : tout ce qui décrit « ce qui tourne et à quoi c'est connecté » pend d'elle. Le groupe Ansible n'est plus une cible de liaison — seulement une capacité qu'une VM fournit (le rôle appliqué).
2. Les registres (source unique de vérité)
Tous sous docs/, machine-lisibles, validés, consommés par le GUI, le CLI et Ansible.
| Registre | Décrit | Champs clés |
|---|---|---|
nomenclature.yml |
nommage & adressage | fonctions (catégorie/service), categories (VLAN/sous-réseau/passerelle), supernet |
serveurs.yml |
les VM du plan | fonction, etat (actif/planifie), placement Proxmox (noeud/stockage/disque/memoire/coeurs), integrations (les clients_*) |
applications.yml |
les applications | groupe (capacité/rôle), hote (VM), port, requiert, expose, (+ bases via consommateur) |
bases-donnees.yml |
serveurs de BD + bases | serveurs_bd ; bases_donnees : serveur/base/proprietaire/secret(Vault), consommateur + portee (application/groupe/hote), usage |
domaines.yml |
zones DNS publiques | domaines_publics : autorite, edge, secondaires, dnssec, mail |
dependances-groupes.yml |
prérequis entre groupes | requiert_groupes_actifs |
Dérivations clés
- Nommage/adressage : tout part de la
fonctionde l'hôte (web-frontal-03).VMID = 9·catégorie·service·NN,VLAN = catégorie.vlan,IP = 10.0.<vlan>.(service×10 + NN). Voirdocs/nomenclature-vm.md. - DSN (lien application↔base) :
<type>://<proprietaire>:<secret>@<hôte>:<port>/<base>. Une application reçoit les bases où(portee=application ET consommateur=elle)OU(portee=groupe ET consommateur=son groupe)OU(portee=hote ET consommateur=son hôte). - Exposition DNS :
application.expose: [fqdn]+ l'edgedu domaine parent →serveur_nginxgénère le vhost (application → hôte → IP:port).
3. La génération (méta-classe)
make instancier produit hosts.yml depuis le plan :
- host vars :
ansible_host/ansible_user+proxmox_*(IP/VMID/VLAN/passerelle dérivés de la nomenclature ; placement/taille depuisserveurs.yml). - groupes d'une VM = socle (
serveur_debian+serveur_durci)- services (les
groupedes applications de l'hôte) - intégrations (
serveurs.yml: integrations) - état (
hotes_actifs/hotes_planifies).
- services (les
La comparaison est sémantique (via ansible-inventory --list, formatage
ignoré). « Diff vide » = le plan reproduit exactement l'inventaire courant ;
c'est le feu vert pour appliquer.
4. Le flux de travail
éditer le PLAN ──▶ make instancier (revoir le diff) ──▶ make instancier-appliquer ──▶ déployer
(GUI ou CLI) (que va-t-il changer ?) (régénère hosts.yml) (make deployer)
Via le GUI — make inventaire-ui
Cinq vues :
| Vue | Rôle |
|---|---|
| Inventaire | lecture seule (inventaire généré) — vue d'ensemble des hôtes |
| Serveurs | éditer les VM du plan : fonction/état/placement/intégrations (VMID·IP·VLAN dérivés en direct) ; bouton « Appliquer le plan » |
| Chaîne | vue holistique par hôte : groupes → rôles, et par application ses expose / requiert / bases (DSN) |
| Applications | éditer les applications : groupe/hôte/port/requiert/expose |
| Bases | éditer serveurs de BD et bases (portée + consommateur), DSN affiché |
Édition → Sauvegarder (écrit le registre) → Appliquer le plan (régénère
hosts.yml). L'écriture directe de l'inventaire est refusée (409).
Via le CLI / make
Chaque registre a son script miroir et ses cibles make :
| Domaine | Lister | Vérifier | Bootstrap (depuis l'inventaire) |
|---|---|---|---|
| Serveurs | make serveurs |
make serveurs-verifier |
make serveurs-bootstrap |
| Applications | make applications |
make applications-verifier |
make applications-bootstrap |
| Bases | make bases |
make bases-verifier |
— |
| Domaines | make domaines |
make domaines-verifier |
— |
Génération :
make instancier # génère hosts.genere.yml (gitignoré) + diff sémantique
make instancier-appliquer # régénère hosts.yml (refuse si diff non vide ; FORCE=1 pour forcer)
Validation globale : make inventaire-verifier (ansible-inventory + tous les
registres + node --check du JS du GUI).
5. Garde-fous
- Validateurs : chaque registre est validé (références connues, énumérations,
unicité). Un
exposesans domaine parent, unrequiertfantôme, uneporteeinconnue, unefonctionabsente → rejet. - Diff vide :
instancier-appliquerrefuse d'écraser l'inventaire si le plan ne le reproduit pas (saufFORCE=1pour un changement intentionnel). node --check: le JS embarqué du GUI est vérifié (scripts/verifier_gui.py, intégré àmake inventaire-verifier) — une erreur de syntaxe JS casse toute la page.- git :
hosts.ymlest versionné ;git diff/git checkoutest le filet. - Secrets : jamais en clair ;
secret:nomme une variable Ansible Vault.
6. Réutilisation de la règle (Ansible)
La règle de résolution vit une seule fois, en Python (scripts/inventory_rules.py),
et est exposée à Ansible par un filter plugin (filter_plugins/registres.py) :
bases_de_application, applications_de_hote, expositions_des_applications,
chaine_connexion. Les playbooks par application (serveur_web_dorsal/_frontaux)
itèrent ainsi sur les applications de l'hôte et résolvent leurs DSN.
7. Amorçage / reconstruction
Pour (re)construire le plan depuis un inventaire existant :
make serveurs-bootstrap # VM -> instance/plan/serveurs.yml (fonction/état/placement/integrations)
make applications-bootstrap # services serveurs_* (hors socle) -> instance/plan/applications.yml
make instancier # vérifier le diff vide
C'est ainsi que le plan a été initialisé sans perte, avec diff vide vérifié.
8. Moteur et instance : deux dépôts
Le moteur (ce dépôt, Set-OPS) est générique et partageable ; il ne contient
aucune donnée d'instance. Une instance (le plan + l'inventaire d'un loup) vit
dans son propre dépôt (ex. OPS-monatelier).
Le moteur localise l'instance via SETOPS_INSTANCE (défaut : instance). Deux
modèles :
- Modèle A — dépôts frères (en cours) : moteur et instance côte à côte ; un
symlink
instance -> ../OPS-monatelier(gitignoré) fait que le défaut résout l'instance sans configuration. Idéal quand on développe le moteur et l'instance. - Modèle B — moteur en sous-module (futur, pour la meute) : l'instance épingle
une version du moteur ;
SETOPS_INSTANCEpointe la racine de l'instance.
Pour brancher une instance (modèle A) :
cd Set-OPS
ln -s ../OPS-monatelier instance # ou : export SETOPS_INSTANCE=/chemin/instance
make inventaire-verifier # lit l'instance via le symlink
Le moteur écrit hosts.yml (généré) dans le dépôt d'instance, jamais dans le sien.