# CHANGELOG — Set-OPS ## 2026-06-24 ### Modifié - **Consolidation minimale post-diagnostic (ménage documentaire, sans risque).** Suite à une relecture à froid « auteur » de l'état réel du dépôt. (1) **En-tête généré rafraîchi** : `instance/inventories/production/hosts.yml` pointait encore vers l'ancienne source `docs/` ; régénéré via `instancier-appliquer` (diff sémantique **vide** — contenu inchangé, seul l'en-tête a bougé ; commité côté instance `OPS-Chezlepro`). (2) **`docs/catalogue-services.md`** : nouvelle section **« État d'implémentation des rôles »** qui distingue sans ambiguïté les rôles **implémentés** (validés *en tant que code*, **non éprouvés en prod**), les **échafaudages** (playbooks-ancres `debug` sans rôle : `serveur_nextcloud`, `serveur_collabora`, `client_supervision`, `serveur_web_frontal`, `serveur_web_dorsal`) et les **rôles-catégories inertes** (`applications`, `backup`, `database`, `identity`, `monitoring`, `proxmox`, `storage`, `web` — vestiges d'un regroupement par catégorie abandonné, l'architecture réelle étant plate `serveur_*`/`client_*`) ; colonnes « Rôle futur » → « Rôle ». (3) **`docs/vm-lifecycle.md` §8** : flux de déploiement réaligné sur le plan (`instancier-appliquer` puis `deployer`) au lieu de la commande supplantée `hote-ajouter`. Vérifié : `make verifier` (exit 0), `ansible-lint` 0 échec. **Non touché à dessein** : les références `instance/inventories/lab/` des docs de template sont **correctes** (contexte golden template, distinct de `production`) ; le bas du `README.md` (« Premier chantier »/« Principe ») est daté mais **exact** (template = socle), donc laissé tel quel pour éviter le churn. - **`creer-vm` enfin piloté par le plan — couture « inventaire → création VM » fermée (étape 4 du diagnostic).** `make creer-vm HOTE=` ne prend plus qu'**un argument** : il **lit VMID/IP/CIDR/passerelle/VLAN/stockage/disque/nœud directement dans l'inventaire généré** (comme `deployer` lit ses groupes) au lieu de les redemander à la main, et **n'écrit plus** dans l'inventaire (l'appel à `hote-ajouter` est supprimé — l'hôte est déjà présent via le plan). Repli sur le nœud par défaut de `config` si `proxmox_noeud` absent. Les 3 cibles legacy `hote-ajouter` / `hote-planifier` / `hote-groupes` (qui éditaient l'inventaire généré à la main — anti-pattern) sont **neutralisées** : refus explicite renvoyant vers `serveurs.yml` + `instancier-appliquer`. `aide` et docs (`README`, `QUICKSTART`, `procedure-template-debian13-proxmox`) alignées sur `creer-vm HOTE=…`. La chaîne déclarative est désormais **continue** : `plan → instancier-appliquer → creer-vm HOTE → (activer) → deployer HOTE`. Activation laissée **manuelle** (édit du plan, par décision). Vérifié : `make verifier` exit 0 (dont 4 tests unitaires), extraction testée sur l'inventaire réel (`data-01` avec nœud, `collab-01` sans nœud → repli), chemins de refus (HOTE vide, hôte absent, cibles legacy) exit 2. *(Clonage réel non exécuté : exige Proxmox — c'est la preuve VM, étape suivante.)* - **Neutralisation complète pour partage public (« 100 % neutre »).** Préparation au don public du moteur : suppression de **toute** trace Chezlepro de l'**outil** (rôles, scripts, docs publiques, exemples, LICENSE) — prouvée par scan exhaustif (`git grep` revient **vide** pour `chezlepro`, pour `asgard`/`TrueNAS`, et pour le supernet réel `10.1.x`). Corrigés au passage **5 défauts de généricité fonctionnels** qui auraient déployé du Chezlepro chez tout hébergeur : `roles/motd/templates/motd.j2` (« Système Chezlepro » → `{{ domaine_interne | default('Set-OPS') }}`), `serveur_forgejo` (`APP_NAME`), `serveur_openldap` (organisation par défaut), `serveur_step_ca` (nom d'AC par défaut), et surtout les **IP réelles codées en dur dans les `defaults`** de plusieurs rôles (`db_host`, `loki_url`, `reseaux_autorises` → plage d'exemple `10.0.x`). Noms de tâches/playbooks et exemples de README généricisés ; marqueurs de fichiers gérés alignés sur `setops` (READMEs en retard) ; placeholder GUI neutralisé. **LICENSE : copyright → Alliance Boréale.** Fichiers **mainteneur** (`AGENTS.md`, `CLAUDE.md`, `SOLUTION.md`, doc Codex) et `CHANGELOG` conservés (couche gouvernance/historique — peuvent nommer Chezlepro, par décision). L'instance `OPS-Chezlepro` **surcharge déjà** ses vraies valeurs de topologie dans ses `group_vars` : la séparation moteur/instance tient, le changement des `defaults` ne casse pas Chezlepro (seule `client_journal_loki_url` reste à surcharger côté instance). Vérifié : `make verifier` exit 0 (4 tests), 42 fichiers, scans de fuite **vides**. ### Ajouté - **Sous-commande `inventory_host.py parametres-proxmox --hote X`** : émet, machine-lisible (`SETOPS_*='valeur'`), les paramètres de clonage Proxmox d'un hôte lus dans l'inventaire généré ; refuse si l'hôte est absent ou s'il manque un champ requis (VMID/IP/CIDR/passerelle/VLAN). Consommée par `make creer-vm`. **Premier test stdlib du dépôt** `scripts/tests/test_inventory_host.py` (sans pytest) + cible **`make test`**, câblée dans `make verifier`. ## 2026-06-23 ### Corrigé - **Robustesse du moteur pour une instance hors dépôt (révélé par une instance d'essai agnostique).** Les scripts affichaient des chemins via `Path.relative_to(RACINE)`, qui **lève** quand l'instance est en dehors du dépôt (`SETOPS_INSTANCE` pointant un chemin externe, ex. `../OPS-laPreuve`). Remplacé par `os.path.relpath` (`scripts/instancier.py`, `inventory_gui.py`, `config_proxmox.py`). Le moteur génère désormais correctement depuis n'importe quel emplacement d'instance — agnosticité prouvée (instance `lapreuve.local` / `10.9.0.0/16` : inventaire distinct, **zéro fuite Chezlepro**). ### Modifié - **Dette doc soldée après le découpage moteur/instance.** Rafraîchissement des chemins dans les docs secondaires, README de rôles, messages et docstrings : `inventories/...` → `instance/inventories/...`, `docs/.yml` → `instance/plan/.yml`. Correction au passage de chemins de playbooks périmés (préexistants) dans `CLAUDE.md`/`SOLUTION.md` : `playbooks/vm_templates/debian13_proxmox_prepare|verify|cleanup.yml` → `playbooks/modeles_vm/debian13_proxmox_preparer|verifier|nettoyer.yml`, et `confirm_template_cleanup` → `template_cleanup_confirm`. Validé : diff vide, `ansible-lint` 0 échec, `make inventaire-verifier`. - **Découpage moteur/instance — Phase 3 (modèle A) : deux dépôts.** Le contenu de `instance/` (plan + inventaire) part dans un **dépôt d'instance dédié** (`OPS-Chezlepro` pour Chezlepro, sur la forge). `Set-OPS` devient le **moteur pur** (rôles, scripts, playbooks, guides, exemples). L'instance est **montée via un symlink** `instance -> ../OPS-Chezlepro` (gitignoré) : le défaut `SETOPS_INSTANCE=instance` la résout sans configuration. Le moteur lit le plan et **régénère `hosts.yml` dans le dépôt d'instance**. `.ansible-lint` exclut `instance/`. Validé : diff vide, `ansible-lint` 0 échec, `make inventaire-verifier`, `instancier-appliquer`. **Modèle A (dépôts frères)** retenu jusqu'à preuve du concept ; le **modèle B (moteur en sous-module)** pour la meute viendra ensuite. Le moteur ne contient plus aucune donnée Chezlepro. - **Découpage moteur/instance — Phase 2b : sortir l'inventaire dans `instance/inventories/`.** L'inventaire (hôtes générés, `group_vars`, vault) quitte `inventories/` pour `instance/inventories/`. Suivent : `ansible.cfg`, le `Makefile` (`export SETOPS_INSTANCE ?= instance`, chemins dérivés), les scripts (`INSTANCE / "inventories/..."`), `config_proxmox.py`, `.gitignore`. Les docs primaires (`AGENTS.md`, `README.md`, `docs/plan-et-generation.md`, `docs/architecture-set-ops.md`) reflètent le layout `instance/`. Non destructif : diff vide, `ansible-lint` 0 échec, `make inventaire-verifier` OK. *(Docs secondaires à rafraîchir ; Phase 3 : deux dépôts.)* - **Découpage moteur/instance — Phase 2a : sortir le plan dans `instance/plan/`.** Les 5 registres (`serveurs`, `applications`, `bases-donnees`, `domaines`, `nomenclature`) quittent `docs/` pour `instance/plan/`. Les scripts les localisent via **`SETOPS_INSTANCE`** (variable d'env, défaut `/instance`) ; les rôles/playbooks via **`setops_plan_dir`** (group_vars d'instance). `docs/` ne garde que les guides `.md` + `dependances-groupes.yml` (moteur). `.ansible-lint` exclut `instance/plan/` (registres de données). Non destructif : diff vide, `ansible-lint` 0 échec, `include_vars` via `setops_plan_dir` testé. *(Phase 2b : sortir l'inventaire ; Phase 3 : deux dépôts.)* - **Découpage moteur/instance — Phase 1b : neutraliser la marque `chezlepro`.** Les noms de fichiers gérés par les rôles (`99-chezlepro.conf`, `chezlepro_filter`, `chezlepro-bind.conf`, `/etc/redis/chezlepro.conf`, etc.) et les 14 templates correspondants passent à la marque neutre du moteur **`setops`** (`git mv` + références `src`/`dest`). Un loup ne déploie plus de fichiers marqués « chezlepro ». Cohérence `src ↔ template` vérifiée, `ansible-lint` 0 échec, diff vide. (Les README gardent leurs exemples ; génériciser plus tard.) - **Découpage moteur/instance — Phase 1 : délier les rôles du domaine Chezlepro.** Introduction d'une variable d'identité d'instance **`domaine_interne`** (dans `inventories/*/group_vars/all.yml`). Les 13 rôles qui codaient `chezlepro.internal` en dur (zones DNS, FQDN, relais SMTP, AC, etc.) utilisent désormais `{{ domaine_interne }}` ; le `base_dn` LDAP et le domaine court sont **dérivés** (`dc={{ domaine_interne.split('.') | join(',dc=') }}` → `dc=chezlepro,dc=internal`, ou `dc=acme,dc=local` pour un autre loup). Comportement **identique** pour Chezlepro (qui pose `domaine_interne: chezlepro.internal`), mais le moteur devient générique — première brique pour partager l'outil à la meute (`docs/positionnement.md`). Ajout d'`exemples/instance.exemple.yml`. Non destructif : diff de génération vide, `ansible-lint` 0 échec. *(La marque `chezlepro` sur les noms de fichiers gérés — `99-chezlepro.conf`, `chezlepro_filter` — sera neutralisée en Phase 1b ; sortie du plan en Phase 2 ; deux dépôts en Phase 3.)* ### Ajouté - **Principe gravé : Set-OPS exploitable par un humain SANS IA.** Ajouté comme principe #10 d'`AGENTS.md` (règle pour le mainteneur : ne jamais introduire de fonctionnalité qui exige une IA) **et** en face humaine dans le `README` (survit à la livraison sans les fichiers IA). La doc / `make` / GUI sont l'interface primaire et complète ; l'IA n'assiste que le mainteneur, jamais l'utilisateur. `AGENTS.md`/`CLAUDE.md` ne font pas partie de l'outil livré. (Souveraineté jusqu'au bout : pas de dépendance aux géants remplacée par une dépendance à une IA.) - **Accueil d'un nouvel hébergeur (parcours à froid).** Nouveau **`QUICKSTART.md`** : le chemin linéaire « de zéro à ton écosystème déployé sur ta grappe Proxmox » (cloner le moteur → choisir un modèle → créer son instance + symlink → renseigner → `make config` + secrets → **construire le golden template une fois** → `instancier` → `cloner-vm` → activer + `deployer`), honnête sur les prérequis et le seam création-de-VM. `README.md` réorienté : « moteur générique qu'un hébergeur peut utiliser » (plus « infra de Chezlepro »), avec pointeur QUICKSTART. **Garde-fou `_instance-requise`** dans le Makefile : si l'instance manque, message utile (liste des modèles + QUICKSTART) au lieu d'un faux « valide » silencieux, sur `instancier`/`instancier-appliquer`/`inventaire-ui`/`inventaire-verifier`/`deployer`. `make aide` route vers QUICKSTART. - **Catalogue de modèles d'écosystèmes prêts à déployer (`exemples/modeles/`).** Un hébergeur copie le modèle qui colle à son offre, le renseigne à ses couleurs (ou celles de son client) et instancie — plus besoin de démonstrateur. Structure **socle + modules + presets** : un socle souverain (DNS interne, AC/PKI, edge TLS, relais courriel) + des modules (web, identité, forge, observabilité, collaboration). Modèles livrés et validés (chacun génère un écosystème distinct, **zéro fuite Chezlepro**, IPs `10.10.x`) : **`socle`** (4 VM), **`presence-web`** (7), **`forge`** (6), **`identite`** (LDAP+Keycloak, 6), **`observabilite`** (Prometheus/Loki/Grafana+Icinga, 7), **`integral`** (11). **`collaboration`** (Nextcloud/Collabora) reste à construire (rôles non implémentés). `.ansible-lint` exclut `exemples/`. Remplace l'instance d'essai jetable. - **`docs/positionnement.md` — décision de positionnement vs l'existant.** Acte que le cœur de Set-OPS (plan déclaratif → génération d'inventaire) recoupe **NetBox/Nautobot** (+ `nb_inventory`), le GUI d'exécution recoupe **AWX/Semaphore**, le « la définition instancie la flotte » recoupe **NixOS+Colmena / Terraform**, et le modèle application-pivot recoupe **Backstage**. Décision en vigueur : on **garde** le plan de contrôle maison (souverain, bien dimensionné pour ~13 VM) mais on **gèle son périmètre** ; seuils explicites d'adoption de l'outil mûr (RBAC/audit → AWX ; IPAM/source de vérité partagée → NetBox). Règle ancrée dans `AGENTS.md`. - **Documentation — passe complète (le dépôt « dit ce qu'il fait »).** Nouveau guide central **`docs/plan-et-generation.md`** : le modèle (entités + liens), les registres et leurs schémas, la référence des commandes `make`/CLI et des vues GUI, le flux « éditer le plan → `instancier` → appliquer », les garde-fous. `AGENTS.md` gagne la section « Le plan et la génération de l'inventaire » (règle d'or : `hosts.yml` est généré, ne pas l'éditer). `README.md` : section « Le plan : on édite, l'inventaire se génère » + remplacement du flux legacy `hote-planifier`/`ajouter` par le flux par le plan. Rafraîchissement de `docs/architecture-set-ops.md` (entités du plan), `docs/nomenclature-vm.md` et `docs/catalogue-services.md` ; correction de la terminologie **domaine → fonction** dans la prose (collision avec le DNS levée jusque dans la doc). ### Modifié - **Noms de rôles et playbooks au singulier.** `serveurs_*` → `serveur_*`, `clients_*` → `client_*`, et suffixes pluriels au singulier (`serveur_web_dorsal`/`serveur_web_frontal`, `client_metrique`, `client_journal`). Renommage par **tokens exacts** : répertoires de rôles, playbooks de groupes, `group_vars`, **variables internes des rôles** (`serveur_nginx_*`, conformité `ansible-lint`), groupes du plan (`applications.yml`, `serveurs.yml: integrations`), constantes de code (`GROUPES_OPERATIONNELS_PREFIXES`, sockle), docs. Les faux-amis sont **préservés** (`serveurs_bd` clé du registre BD, `scripts/serveurs.py`, fonctions Python). Les groupes d'état restent au pluriel (`hotes_actifs`/`hotes_planifies`/`modeles_vm`). Validé : `ansible-lint` 0 échec (0 var-naming), **diff vide** de la génération, `node --check`, tous les registres. Ajout de `.ansible-lint` excluant `docs/` (registres de données, pas du contenu Ansible). - **Rework GUI : l'UI édite le plan (branche `bascule-inventaire-genere`).** La vue **Serveurs** devient éditable (fonction / état / placement Proxmox / intégrations `clients_*`, avec VMID/IP/VLAN dérivés en direct), avec « + Serveur », « Sauvegarder les serveurs » (`POST /api/serveurs`) et **« Appliquer le plan → hosts.yml »** (`POST /api/instancier` → `instancier appliquer`). La vue **Inventaire** passe en **lecture seule** : bandeau explicite + l'écriture directe (`POST /api/inventaire`) est refusée (409) puisque `hosts.yml` est désormais généré. Tout passe par le plan (`serveurs.yml` / `applications.yml`) puis « Appliquer ». Garde-fou JS `node --check` exécuté à chaque étape. - **Bascule méta-classe (branche `bascule-inventaire-genere`).** `make instancier-appliquer` régénère `inventories/production/hosts.yml` **depuis le plan** (refuse si le diff n'est pas vide, sauf `FORCE=1` pour un changement intentionnel ; git sert de filet). Effectuée avec diff vide vérifié : `hosts.yml` est désormais un artefact généré, sémantiquement identique à l'ancien (vérifié par `make inventaire-verifier` complet + chargement GUI). À ce stade le GUI édite encore `hosts.yml` directement (rework à venir) : éditer le **plan** (`serveurs.yml`/`applications.yml`) puis `make instancier-appliquer`. - **Phase 2 (début) — vue Chaîne holistique.** Dans `make inventaire-ui`, la vue Chaîne montre désormais, pour chaque application d'un hôte, l'ensemble de ses liens : `expose` (FQDN publics), `requiert` (applications dont elle dépend) et ses bases (DSN), plus son port. On voit d'un coup d'œil comment VM, applications, bases et domaines s'articulent. - **Phase 1b — clarté de nommage.** La clé `domaines:` de `docs/nomenclature.yml` (familles fonctionnelles : `infra-pki`, `web-frontal`…) est renommée **`fonctions:`** pour lever la collision avec les domaines DNS (`docs/domaines.yml`). L'auto-proposition du GUI suit (`fonctionDe` / `infoFonction`, `nomenclature.fonctions`, libellés « Fonction inconnue… », placeholder `fonction-NN`). Aucun rôle ni inventaire impacté : la nomenclature n'est consommée qu'au moment de la planification. - **Refonte « application-hub », Phase 1 — les liens deviennent explicites (inventaire inchangé, zéro régression).** L'application porte désormais tous ses liens : `groupe` (capacité/rôle), `hote` (VM), `port`, **`requiert`** (autres applications dont elle dépend) et **`expose`** (FQDN publics qui la publient). L'**exposition DNS quitte `docs/domaines.yml`** (le bloc `exposition` est retiré) et vit sur l'application via `expose` ; `docs/domaines.yml` ne décrit plus que les zones (autorité, edge, secondaires, dnssec, mail). `serveurs_nginx` dérive ses vhosts des **applications** (`expose` + edge du domaine), résolvant `application → hôte → IP` (rôle + `expositions.conf.j2` réécrits). Nouvelle règle partagée `expositions_des_applications` (+ `domaine_parent`) dans `inventory_rules.py`, exposée à Ansible par le filter plugin ; `valider_applications` valide `requiert` (applis connues), `expose` (domaine parent déclaré) et `port`. CLI (`applications.py --port/--requiert/--expose`, `domaines.py` affiche les expositions dérivées) et **GUI** (champs Port/Requiert/Expose sur la fiche Application, persistés) suivent ; l'API expose aussi le registre des domaines. Le groupe n'est plus une cible de liaison, seulement une capacité. *(Renommage `nomenclature.domaines:` → `fonctions:` reporté en Phase 1b ; génération de l'inventaire depuis le plan en Phase 3.)* ### Ajouté - **Phase 3 — générateur d'inventaire depuis le plan (non destructif ; diff vide prouvé).** `make instancier` (`scripts/instancier.py`) génère `inventories/production/hosts.genere.yml` (gitignoré, artefact) depuis le plan — `docs/serveurs.yml` + `docs/applications.yml` + `docs/nomenclature.yml` — puis **compare sémantiquement** (via `ansible-inventory --list`, formatage ignoré) avec l'inventaire actuel : host vars dérivés (IP/VMID/VLAN/passerelle de la nomenclature, placement/taille du registre serveurs), groupes dérivés (socle `debian`/`durcis` + services depuis les applications + intégrations `clients_*` + état). Prérequis posés : `make applications-bootstrap` (services `serveurs_*` → applications) et `serveurs.yml` enrichi d'`integrations` (les `clients_*` par VM, capturés au bootstrap). **Résultat : DIFF VIDE — le plan reproduit exactement les 13 hôtes de l'inventaire.** La bascule (rendre `hosts.yml` généré et faire éditer le plan par l'UI) reste **non effectuée** : elle attend une validation explicite. - **Phase 2 — le serveur (VM) entre dans le plan (lecture seule, l'inventaire reste autorité).** Nouveau registre `docs/serveurs.yml` (VM = `fonction` + `etat` + placement/dimensionnement Proxmox), **bootstrapé depuis l'inventaire** (`make serveurs-bootstrap`). La dérivation nomenclature (fonction + rang → VMID/IP/VLAN/passerelle) est portée en Python (`deriver_nomenclature`, source unique, miroir de l'auto-proposition du GUI) et la **réconciliation** compare le dérivé aux valeurs de l'inventaire (`reconcilier_serveur`). CLI `scripts/serveurs.py` (`lister`/`verifier`/`bootstrap`) + cibles `make serveurs` / `serveurs-verifier` / `serveurs-bootstrap`, intégré à `make inventaire-verifier`. GUI : vue **Serveurs** (lecture seule) affichant le plan + valeurs dérivées + statut de réconciliation. Bootstrap initial : **13 serveurs, tous réconciliés** (le dérivé reproduit exactement l'inventaire → la génération de Phase 3 pourra viser un diff vide). - **Application = entité de première classe** (une VM peut porter plusieurs applications). Nouveau registre `docs/applications.yml` (`application → groupe, hote`). Les bases se lient via `consommateur` + **`portee`** (`application` | `groupe` | `hote`, défaut `groupe`) dans `docs/bases-donnees.yml` : une application `A` (groupe `G`, hôte `H`) reçoit les bases où `(portee=application ET consommateur=A) OU (portee=groupe ET consommateur=G) OU (portee=hote ET consommateur=H)` — plusieurs DSN par application. Résolution + validation partagées dans `inventory_rules.py` (`charger_applications`, `valider_applications`, `applications_de_hote`, `bases_de_application`, `PORTEES_BD` ; `valider_bases` croise désormais `portee=application` avec le registre des applications). CLI `scripts/applications.py` (`lister`/`verifier`/`ajouter`/`retirer`) + `scripts/bases_donnees.py --portee` ; cibles `make applications` / `applications-verifier` ; validation intégrée dans `make inventaire-verifier`. GUI : vue **Applications** (CRUD), sélecteur de **portée** + consommateur dynamique (groupe/hôte/application) dans la vue Bases, et **vue Chaîne par application** (DSN résolus par hôte). Filter plugin `filter_plugins/registres.py` exposant la **même** règle de résolution à Ansible (source unique) ; les playbooks `serveurs_web_dorsaux` / `serveurs_web_frontaux` itèrent désormais sur les applications de l'hôte et résolvent leurs bases (scaffold ; le déploiement applicatif réel s'y insère). Les services en grappe (keycloak/icingadb/forgejo) restent en `portee: groupe` (inchangés). - Vhosts `serveurs_nginx` **dérivés du registre `docs/domaines.yml`** (bloc `exposition`) : pour chaque exposition `web` ciblant cet edge, un vhost est généré (`expositions.conf.j2`) avec amont = `amont` explicite, sinon `http://:` résolu depuis l'inventaire ; une exposition non résolvable (cible sans hôte actif, ou sans port) est listée mais non publiée. Variables `serveurs_nginx_groupe` (edge ciblé) et `serveurs_nginx_publier_expositions` (bascule). Les sites déclarés à la main continuent de coexister. Ajout du `port: 3000` à l'exposition `forge`. ## 2026-06-22 ### Ajouté - Registre déclaratif des domaines publics `docs/domaines.yml` (publication externe des hostnames), symétrique de `docs/bases-donnees.yml`. Modèle d'autorité retenu : **primaire caché + secondaires** (PowerDNS backend PostgreSQL + API non exposé, secondaires publics via AXFR/TSIG). Bloc **`exposition`** = binding `nom public → service interne (cible) → edge`, destiné à trois consommateurs (génération de zone publique, vhosts `serveurs_nginx`, noms à certifier ACME). Validation partagée dans `inventory_rules.py` (`charger_domaines`, `valider_domaines`, `fqdn_exposition`, `expositions_du_groupe` ; autorités connues `primaire-cache|auto-heberge|delegue`, `edge` requis, FQDN uniques). CLI miroir `scripts/domaines.py` (`lister`/`verifier`) + cibles `make domaines` / `make domaines-verifier`, et validation intégrée dans `make inventaire-verifier`. Première entrée réelle : `forge.alliance-boreale.ca → serveurs_forgejo` (DNSSEC, secondaires et enregistrements mail laissés à renseigner). - Formalisation de l'identité du dépôt : `AGENTS.md` (nouvelle section « Mission et identité ») et `README.md` (section « Mission ») actent que `Set-OPS` **définit et construit l'écosystème numérique souverain de Chezlepro Inc.** — piliers (identité, confiance, nommage/adressage, données, communication, observabilité/supervision, applicatif), propriétés (souverain, déclaratif/convergent) et limites honnêtes (pas d'auto-remédiation ; en grande partie défini/validé avant déploiement réel). Le template Debian 13 reste la fondation, pas la finalité. - Gestion des bases de données dans la GUI et la CLI : vue « Bases » de `make inventaire-ui` présentant les serveurs de BD, les bases applicatives et leurs **chaînes de connexion** (mot de passe masqué), avec gestion complète (ajout / édition / retrait) et endpoint `POST /api/bases` (validé, jeton). CLI `scripts/bases_donnees.py` (`lister` / `verifier` / `ajouter-serveur` / `ajouter-base` / `retirer-*`) + cibles `make bases` et `make bases-verifier`. Le registre est désormais validé dans `make inventaire-verifier`. GUI et CLI partagent les mêmes règles (`inventory_rules`). - Rôle `serveurs_forgejo` (forge Git, Phase 5) : binaire officiel Forgejo (version épinglée + lien symbolique), utilisateur `git`, **base PostgreSQL via le registre** (4e consommateur, entrée `forgejo`), publication derrière `serveurs_nginx` (`HTTP_ADDR=127.0.0.1`, `INSTALL_LOCK`), secrets (BD + `SECRET_KEY` + `INTERNAL_TOKEN` + admin) via Vault, mailer vers `serveurs_sendmail`, compte administrateur initial créé une fois. Détails d'installation tirés de la doc officielle Forgejo. Activation de l'entrée `forgejo` dans `docs/bases-donnees.yml`. Playbook de groupe et `group_vars` production associés. - Rôle `serveurs_icinga` (supervision active — cœur, Phase 4) : dépôt apt officiel Icinga, `icinga2` + `icingadb` + `icingadb-redis`, `icinga2 api setup` + activation de la fonctionnalité `icingadb`, **base PostgreSQL via le registre** (entrée `icingadb`, import du schéma, mot de passe partagé via Vault), config Icinga DB (BD + Redis). **Icinga Web 2 différé** à une phase dédiée. Détails de configuration Icinga DB paramétrés et signalés comme non vérifiables verbatim (pages doc partiellement indisponibles). Ajout de l'entrée `icingadb` à `docs/bases-donnees.yml`. Playbook de groupe et `group_vars` production associés. - Rôle `serveurs_redis` (cache / files, paquet Debian) : surcharge **non destructive** de `redis.conf` via `include`, `requirepass` (Vault, car exposé sur le réseau interne), `maxmemory` + politique `allkeys-lru`, écoute localhost + IP interne. Complète le nœud données (data-01) aux côtés de PostgreSQL. Playbook de groupe et `group_vars` production associés. - Rôle `clients_smtp` (intégration cliente relais mail) : `msmtp` + `msmtp-mta` relaient le courrier sortant (notifications, cron, alertes) vers `serveurs_sendmail`, sans daemon. Dernière intégration cliente dont le serveur central existe. Playbook de groupe et `group_vars` production associés. - Rôle `clients_ldap` (intégration cliente identité utilisateur) : **SSSD** (NSS + PAM) vers `serveurs_openldap`, activation de `sss` dans `/etc/nsswitch.conf` (passwd/group/shadow), création automatique des répertoires personnels (`mkhomedir`), bind anonyme par défaut (bind dédié possible via Vault). Authentification des utilisateurs centralisée — complète l'identité machine de `clients_pki`. Playbook de groupe et `group_vars` production associés. - Rôle `clients_pki` (intégration cliente PKI / identité machine) : `step-cli` (dépôt Smallstep), **confiance** dans l'AC interne (`step ca bootstrap --install` → racine dans le magasin système), **certificat d'hôte** via le provisioner, **renouvellement automatique** (unités systemd officielles `cert-renewer@.{service,timer}`, vérification toutes les 15 min). Chaque hôte obtient une identité machine vérifiable et un TLS interne réel (remplace les certificats auto-signés). Secrets (empreinte racine + mot de passe provisioner, partagé avec `serveurs_step_ca`) via Vault. Détails tirés de la doc officielle Smallstep. Playbook de groupe et `group_vars` production associés. - Rôle `clients_journaux` (intégration cliente journaux) : **Grafana Alloy** (dépôt apt Grafana) lit le journal système (journald) et le pousse vers `serveurs_loki` ; l'utilisateur `alloy` est ajouté au groupe `systemd-journal`. Complète l'observabilité côté client (métriques + journaux). Playbook de groupe associé. - Rôle `clients_metriques` (intégration cliente métriques) : installe `prometheus-node-exporter` (paquet Debian) sur les VM du groupe ; `serveurs_prometheus` dérive et scrape automatiquement la cible depuis l'inventaire. Première intégration cliente — ferme la boucle d'observabilité côté métriques. Playbook de groupe associé. - Rôle `serveurs_grafana` (tableaux de bord, dépôt apt officiel Grafana) : datasources Prometheus + Loki **provisionnées automatiquement** (`/etc/grafana/provisioning/datasources/`), domaine/`root_url` et mot de passe admin (Vault) via un **drop-in systemd non destructif** (ne touche pas `grafana.ini` du paquet), inscriptions publiques désactivées, publication derrière `serveurs_nginx`. Clôt la Phase 3 observabilité. Playbook de groupe et `group_vars` production associés. - Rôle `serveurs_loki` (agrégation de journaux, dépôt apt officiel Grafana) : configuration single-node (stockage `filesystem`, schéma TSDB v13), rétention via compactor (`retention_enabled`), écoute `:3100`. Le dépôt apt Grafana est partagé avec `serveurs_grafana`. Playbook de groupe associé. - Rôle `serveurs_prometheus` (collecte de métriques, paquet Debian) : début de la Phase 3 observabilité. Config Prometheus avec cibles `node_exporter` **dérivées de l'inventaire** (hôtes actifs de `clients_metriques` → `:9100`, comme la zone DNS), jobs additionnels libres, rétention configurable via `/etc/default/prometheus`, `promtool check config` avant rechargement (handler dans le rôle). Playbook de groupe associé. - Rôle `serveurs_keycloak` (SSO/IAM, hub d'authentification centralisée) : distribution Quarkus (version en variable, URL release officielle), **premier consommateur de bout en bout du registre de BD** (`serveurs_postgresql` crée la base/compte `keycloak`, le rôle lit la même entrée pour son DSN — mot de passe partagé via `vault_bd_keycloak`), publication derrière `serveurs_nginx` (`proxy-headers=xforwarded`, `http-enabled=true`), secrets (BD + admin bootstrap) dans un `EnvironmentFile 0640`/`no_log`, `kc.sh build` puis service systemd `start --optimized`. Activation de l'entrée `keycloak` dans `docs/bases-donnees.yml`. Détails de configuration tirés de la doc officielle Keycloak. Playbook de groupe et `group_vars` production associés. - Rôle `serveurs_openldap` (annuaire interne) : slapd Debian configuré via debconf (installation non interactive, backend MDB), base DN dérivée du domaine (`dc=chezlepro,dc=internal`), mot de passe admin **obligatoire depuis Vault**, unités organisationnelles de base (`people`, `groups`) via `community.general.ldap_entry`. Playbook de groupe et `group_vars` production associés. - Registre déclaratif des bases de données applicatives `docs/bases-donnees.yml` (patron « 1 appli → 1 base → 1 compte propriétaire → 1 chaîne de connexion »). Consommé côté serveur par `serveurs_postgresql` (crée base + compte propriétaire, mot de passe depuis la variable Vault nommée par `secret`) et, côté appli, pour bâtir la chaîne de connexion — secret partagé, source unique. Évite un rôle par base. Vide par défaut. - Rôle `serveurs_step_ca` (AC interne Smallstep step-ca + provisioner ACME) : dépôt apt officiel Smallstep (clé + source deb822), installation `step-ca`/`step-cli`, utilisateur système `step`, initialisation de l'AC **une seule fois** (`step ca init` standalone + ACME, garde-fou `creates: ca.json`), mots de passe CA et provisioner **obligatoires depuis Vault**, unité systemd durcie officielle. Playbook de groupe et `group_vars` production associés. Clôt la Phase 1 des fondations. Détails d'installation tirés de la documentation officielle Smallstep (non inventés). - Rôle `serveurs_sendmail` (relais SMTP sortant, basé sur Postfix qui fournit l'interface `sendmail`-compatible) : installation non interactive (debconf), relais limité à `mynetworks` (`10.1.0.0/16`, pas de relais ouvert), smarthost amont optionnel, TLS opportuniste (snakeoil par défaut), `postfix check` avant reload. Playbook de groupe et `group_vars` production associés. - Rôle `serveurs_nginx` (edge) : reverse proxy et terminaison TLS, certificat auto-signé (snakeoil) par défaut avec chemins en variables pour bascule vers l'AC interne/ACME, durcissement de base (`server_tokens off`, TLS 1.2/1.3), sites de reverse proxy pilotés par variables (vides par défaut), validation `nginx -t` avant reload (handler dans le rôle). Playbook de groupe `serveurs_nginx` et `group_vars` production associés. - Rôle `serveurs_postgresql` (premier service applicatif après PowerDNS) : PostgreSQL packagé Debian 13, écoute `127.0.0.1` + IP interne, `pg_hba` en `scram-sha-256` ouvert au réseau interne `10.1.0.0/16`, configuration via `conf.d`, provisionnement optionnel de comptes/bases par variables (mots de passe via Vault), handlers reload/restart dans le rôle. Playbook de groupe `serveurs_postgresql` et `group_vars` production associés. Ajout de `requirements.yml` (collections `community.postgresql`, `community.general`). - Vue des liens VM → groupes → playbooks → rôles dans `make inventaire-ui` : onglet « Chaîne » par hôte (panneau détail) et vue arbre globale (bascule « Inventaire / Chaîne » en en-tête). Les rôles sont extraits des `playbooks/groupes/*.yml` et exposés dans l'API ; les groupes sans rôle sont signalés « stub ». - Champ de mot de passe du vault Ansible dans la modale de déploiement de `make inventaire-ui` : transmis via fichier temporaire `0600` + `ANSIBLE_VAULT_PASSWORD_FILE`, supprimé après exécution, jamais journalisé. Évite tout prompt `--ask-vault-pass` bloquant en exécution non-interactive. Le flux vault de `make cloner-vm` / `creer-vm` n'est pas modifié. - Catégorie « Modèles / essais » (VLAN 99 → `10.1.99.0/24`) dans `docs/nomenclature.yml`. - Registre de nomenclature machine-lisible `docs/nomenclature.yml` (source unique) : domaines, catégories, plan d'adressage `10.1.0.0/16` segmenté par fonction (un /24 et un VLAN par catégorie), dérivations hostname / VMID / VLAN / IP / passerelle. - Auto-proposition dans `make inventaire-ui` : bouton « ✨ Proposer » et auto-remplissage à la saisie du nom, qui dérivent VMID, VLAN, IP et passerelle depuis `docs/nomenclature.yml` (avec indice de zone). Migration du plan d'adressage interne vers `10.1.0.0/16` (remplace les essais `192.168.12.x`). - Adoption du nom officiel « Set-OPS — Votre artisan numérique » : titre et en-tête de `make inventaire-ui`, et titre du `README.md`. - Déploiement depuis `make inventaire-ui` : boutons « Vérifier » (dry-run `--check --diff`) et « Déployer » (réel) par hôte, avec console de sortie en direct. Garde-fous : jeton anti-CSRF (`X-Jeton`), verrou (une seule exécution à la fois), validation du nom d'hôte (anti-injection), refus si l'hôte n'est pas actif, déploiement bloqué tant qu'une vérification n'a pas réussi (réarmé à chaque sauvegarde), restriction à l'inventaire production. Déploiement non transactionnel (sans rollback) signalé à l'opérateur. - Cible `make verifier-deploiement HOTE=…` : déploiement à blanc (`--check --diff`) d'un hôte selon ses groupes, réutilisée par l'interface. - Refonte de l'interface `make inventaire-ui` : thème sombre dense, grille de cartes d'hôtes groupées par état (Actifs / Planifiés) avec badge de statut coloré, chips de filtre (Tous / Actifs / Planifiés / Bloqués), recherche, et panneau détail maître-détail à onglets (Réseau / Proxmox / Groupes) avec tuiles de chiffres-clés (VMID, mémoire, cœurs, disque, groupes), bascule d'état actif/planifié, panneau de dépendances repliable, raccourci Ctrl/Cmd+S. - Saisie des paramètres de provisioning par hôte dans l'inventaire (variables d'hôte) : `proxmox_cidr`, `proxmox_passerelle`, `proxmox_vlan`, `proxmox_pont`, `proxmox_dns`, `proxmox_noeud`, `proxmox_stockage`, `proxmox_disque_taille`, `proxmox_memoire`, `proxmox_coeurs`, avec validation (VLAN 1-4094, CIDR 0-32, entiers positifs) et round-trip non destructif. Documentées dans `docs/nomenclature-vm.md`. - Scission de la couche applicative web en deux groupes distincts de l'edge `serveurs_nginx` : - `serveurs_web_frontaux` (présentation web : UI, rendu, assets) ; - `serveurs_web_dorsaux` (application web : API, traitement) ; - playbooks homonymes et entrée dédiée dans `docs/catalogue-services.md`. - Ajout de `make hote-planifier` pour renseigner un hôte, son VMID et ses groupes sans création ni déploiement immédiat. - Ajout de `scripts/inventory_rules.py` pour centraliser les règles partagées entre la gestion CLI et l'interface locale d'inventaire. - Ajout de `docs/dependances-groupes.yml` comme registre exploitable des dépendances causales entre groupes. - Ajout du contrat `serveurs_powerdns` afin de représenter la capacité DNS centrale requise par `clients_dns`. - Ajout du premier jalon DNS interne : - rôle `serveurs_powerdns` avec PowerDNS Authoritative et backend BIND ; - génération de la zone interne depuis l'inventaire actif ; - rôle `clients_dns` avec validation de zone et modification resolver protégée ; - variables de production DNS et runbook `docs/dns-interne.md`. ### Modifié - Bindings appli↔BD explicites et **plusieurs bases par application** : chaque base porte un `consommateur` (le groupe applicatif qui l'utilise) et un `usage` (principale/cache…). La GUI (vue « Bases » : menu déroulant **Consommateur** + champ **Usage**) et la CLI (`ajouter-base --consommateur --usage`) gèrent le lien ; la vue **Chaîne devient détaillée** (chaque groupe affiche ses rôles ET ses bases avec leur chaîne de connexion). Rôles `serveurs_keycloak`/`serveurs_forgejo`/`serveurs_icinga` migrés pour résoudre leur base par consommateur (plus de clé codée en dur). - Registre `docs/bases-donnees.yml` passé à un **modèle multi-serveurs** : section `serveurs_bd` (serveurs de BD nommés — `type`/`hôte`/`port`/`groupe`) que chaque base référence. La **chaîne de connexion dérivée** devient le lien appli↔BD ; l'hôte n'est plus codé en dur. Rôles `serveurs_postgresql` (filtre par serveur nommé relié à son groupe) et `serveurs_keycloak`/`serveurs_forgejo`/`serveurs_icinga` (hôte/port lus depuis le registre) migrés. - Robustesse du serveur `make inventaire-ui` : `repondre()` avale proprement les connexions fermées par le client (`BrokenPipeError`/`ConnectionResetError`) au lieu de déverser une trace dans la console ; ajout d'un favicon (204) pour éviter le 404 répété du navigateur. - `make deployer` et `make verifier-deploiement` détectent un `group_vars` de production chiffré (Ansible Vault) et demandent le mot de passe **une seule fois** (réutilisé pour tous les playbooks et sous-vérifications via fichier temporaire `0600`, nettoyé en fin de run). Refus propre si vault chiffré détecté en exécution **non-interactive** ; la GUI ferme `stdin` du sous-processus et fournit le mot de passe via la modale, donc elle ne bloque jamais. Ferme l'asymétrie de gestion des secrets entre terminal et GUI. - Migration complète de l'adressage interne vers `10.1.0.0/16` : golden template `basiqueChezlepro` → `10.1.99.99`, et tous les exemples `192.168.x` (README, Makefile, runbooks Proxmox et template) réécrits vers le schéma `10.1.x` / `web-frontal-01`. - Remplacement du groupe `serveurs_web` par `serveurs_web_frontaux` et `serveurs_web_dorsaux` dans les inventaires lab et production, mises à jour des exemples `README.md` et `AGENTS.md`. - Retrait des hôtes de test `web-01` et `web-02` de l'inventaire production. - Planification de la couche applicative web : `web-frontal-01` (95301), `web-frontal-02` (95302) dans `serveurs_web_frontaux` et `web-dorsal-01` (95401) dans `serveurs_web_dorsaux`, tous en `hotes_planifies` avec socle et durcissement. - Mise à jour de `docs/nomenclature-vm.md` : domaines `web-frontal` / `web-dorsal`, retrait des noms de test `web-01`/`web-02`. - Renforcement de la validation d'inventaire : - un hôte doit être soit planifié, soit actif, mais pas les deux ; - un hôte actif doit avoir `ansible_host` ; - un hôte doit porter au moins un groupe opérationnel ; - les VMID dupliqués sont refusés. - Conservation du VMID dans l'inventaire lors de `make creer-vm` et `make hote-ajouter`. - Alignement de l'aide Makefile et de la documentation sur le flux opérateur : planifier, activer/créer, déployer. - Retrait des groupes génériques obsolètes `serveurs_bases_donnees` et `serveurs_supervision` au profit des groupes de services précis. - Consolidation des groupes Icinga en `serveurs_icinga` afin de représenter une seule capacité de supervision serveur sur `mon-01`. - Validation des prérequis actifs avant déploiement d'un groupe, déploiement d'un hôte ou sauvegarde active via l'interface d'inventaire. - Refonte visuelle de `make inventaire-ui` pour afficher les dépendances causales, les prérequis manquants et l'état déployable ou bloqué des hôtes. ## 2026-06-21 ### Ajouté - Ajout de facilités `make` pour exploiter Ansible sur les VM Debian déployées : - diagnostic `ping`, `sudo` et `faits` ; - variables `LIMITE`, `VERIFICATION`, `DIFF`, `ETIQUETTES`, `SAUTER_ETIQUETTES` et `VARIABLES`. - Ajout de facilités `make` pour inspecter et valider les inventaires Ansible : - `hote-ajouter` ; - `hote-groupes` ; - `hote-afficher` ; - `inventaire-verifier` ; - `inventaire-lister` ; - `inventaire-graphe` ; - `inventaire-hote` ; - `inventaire-lab` ; - `inventaire-production`. - Ajout de `deployer` et `deployer-groupe` comme commandes opérateur simplifiées pour appliquer les playbooks de groupes. - Ajout de `scripts/inventory_host.py` pour gérer les entrées d'inventaire et leur appartenance aux groupes sans édition YAML manuelle. - Ajout de la convention `1 groupe opérationnel = 1 playbook homonyme` avec les premiers playbooks : - `playbooks/groupes/serveurs_debian.yml` ; - `playbooks/groupes/serveurs_durcis.yml`. - Ajout du playbook `playbooks/maintenance/verifier_hote_debian.yml` pour valider une VM Debian 13 gérée par Set-OPS après socle et durcissement. - Ajout de directives `AGENTS.md` pour formaliser le `Makefile` comme interface opérateur, la convention groupe/playbook, la francisation de la surface opérateur et les points de stabilisation avant commit. - Ajout du playbook `playbooks/proxmox/cloner_vm_debian.yml` et des cibles `make cloner-vm` / `make creer-vm` pour créer des clones Debian via l'API Proxmox sans stocker de secret dans le dépôt. - Ajout de `inventories/lab/group_vars/proxmox.yml` pour les paramètres Proxmox non sensibles et de `proxmox.vault.yml.example` pour préparer les secrets API avec Ansible Vault. - Ajout de `make config` pour renseigner les paramètres Proxmox et créer ou éditer le Vault API depuis le terminal. ### Modifié - Francisation de la surface opérateur : - variables `make` ; - cibles `make` ; - groupes d'inventaire ; - chemins des playbooks maison ; - libellés du script de gestion d'inventaire. - Documentation du flux de déploiement d'une VM clonée depuis le modèle doré avec les commandes `make`. - Optimisation de la procédure de bootstrap du modèle Debian 13 pour utiliser Cloud-Init comme source unique de l'identité initiale au lieu de maintenir une création manuelle parallèle du compte et de la clé SSH. - Simplification de `make cloner-vm` et `make creer-vm` pour que les paramètres Proxmox communs viennent des variables Ansible plutôt que de la ligne de commande ou de l'environnement. - Ajustement de `make config` pour ne plus redemander les valeurs Cloud-Init déjà portées par le modèle Proxmox. - Déplacement du VLAN hors de `make config` afin de l'exiger explicitement à chaque création de VM avec `VLAN=...`. - Retrait des options `DEMANDER_MDP` et `DEMANDER_SUDO` du `Makefile`; le flux suppose SSH par clé et sudo NOPASSWD déjà fonctionnels. - Retrait des playbooks de couches redondants `playbooks/socle/debian_commun.yml` et `playbooks/durcissement/debian_serveur_durcissement.yml`; la conformité des VM déployées passe maintenant par `playbooks/groupes/`. - Bonification de `AGENTS.md` pour désigner `playbooks/groupes/` comme source officielle de conformité et éviter les cibles `make` de couches parallèles. - Simplification de l'aide du `Makefile` pour exposer d'abord les gestes opérateur : inventaire, groupes, déploiement. - Clarification de `make aide` pour expliquer les différences entre `creer-vm`, `cloner-vm`, `deployer`, `deployer-groupe` et `appliquer`. - Réorganisation de `make aide` par objets d'exploitation : VM, hôtes, groupes, inventaires, modèle et validation. - Retrait des commandes opérateur explicites de ping et sudo; ces vérifications sont maintenant implicites dans `deployer` et `preparer-modele`. - Ajout d'une demande automatique de mot de passe Ansible Vault pour `make cloner-vm` et `make creer-vm` lorsqu'un `proxmox.vault.yml` chiffré est présent. - Amélioration du message d'erreur lorsque `proxmox.vault.yml` ne peut pas être chargé. - Ajustement du playbook Proxmox pour laisser apparaître les erreurs API utiles sans masquer entièrement les échecs de clonage. - Modification de `make deployer HOTE=...` pour appliquer les playbooks correspondant aux groupes de l'hôte. - Ajout d'une vérification explicite de la bibliothèque Python `proxmoxer` avant les appels API Proxmox. - Retrait de la taille disque clone des paramètres Proxmox persistés afin de ne pas tenter de réduire un disque hérité du modèle. - Ajout de la validation inventaire/playbooks pour empêcher un groupe opérationnel avec hôtes sans playbook homonyme. - Ajout du playbook de groupe `serveurs_web` comme point d'ancrage explicite avant l'ajout d'un rôle web. - Ajout d'un catalogue de services pour préparer Keycloak, OpenLDAP, PostgreSQL, Loki, Icinga, Prometheus, Grafana, Forgejo, Sendmail, step-ca, Redis, NGINX, Nextcloud et Collabora. - Ajout des groupes et playbooks homonymes neutres pour les prochains services centraux et intégrations clientes. - Documentation de l'ordre d'implémentation recommandé des services selon leurs dépendances et intégrations. - Ajout d'une nomenclature VM/VMID et distinction entre hôtes planifiés et hôtes actifs dans l'inventaire. - Ajout d'une interface web locale `make inventaire-ui` pour éditer et sauvegarder l'inventaire sans lancer de déploiement. - Ajustement de la nomenclature planifiée vers des noms d'hôtes par domaine afin de permettre la cohabitation de plusieurs services sur une même VM. ## 2026-06-19 ### Ajouté - Structure initiale globale du dépôt Set-OPS. - Playbooks de création du template Debian 13 Proxmox. - Rôles de base Debian. - Rôles de durcissement template-safe. - Playbook de vérification. - Playbook de nettoyage final avant conversion en template. ## 2026-06-20 ### Contexte - Clarification : `Set-OPS` est le dépôt global d’exploitation Ansible de Chezlepro Inc. - Clarification : le template Debian 13 Proxmox est un sous-ensemble du dépôt, pas sa finalité unique. - Clarification : les services applicatifs spécialisés doivent être installés sur les clones par des playbooks dédiés, pas directement dans le template. ### Ajouté - Ajout des directives renforcées dans `AGENTS.md` : - validation Ansible obligatoire ; - vérification des handlers Ansible ; - interdiction de déclarer un playbook prêt si `--syntax-check` échoue ; - préférence pour les correctifs ciblés au lieu des régénérations massives ; - rappel que `Set-OPS` ne doit pas être restructuré autour d’un seul besoin ponctuel. - Ajout d’une logique de template Debian 13 Proxmox : - `playbooks/modeles_vm/debian13_proxmox_preparer.yml` ; - `playbooks/modeles_vm/debian13_proxmox_verifier.yml` ; - `playbooks/modeles_vm/debian13_proxmox_nettoyer.yml`. - Ajout d’une couche de durcissement template-safe : - AppArmor ; - auditd ; - fail2ban SSH ; - unattended-upgrades ; - journald ; - sysctl de sécurité ; - nftables installé et préparé, mais désactivé par défaut dans le template. - Ajout d’un document d’architecture pour les intégrations futures des VM : - supervision ; - métriques ; - identité ; - PKI interne ; - DNS interne. - Documentation détaillée des ajouts appliqués au modèle doré Debian 13 Proxmox depuis une installation minimale. - Ajout d'un runbook explicite pour le playbook de préparation du modèle doré Debian 13 Proxmox. - Ajout d'un runbook manuel précis pour le bootstrap initial de la VM vanille Debian 13 : - correction des sources APT après installation depuis DVD ; - installation minimale de `sudo`, SSH, `cloud-init`, `cloud-guest-utils` et `qemu-guest-agent` ; - utilisation de Cloud-Init pour injecter le compte `ansible`, sa clé SSH, le réseau et le point de bascule vers le `Makefile`. - Ajout d'un document de cycle de vie des VM Chezlepro : - VM vanille ; - goldenisation ; - clonage ; - socle ; - durcissement ; - conformité continue. - Ajout de directives `AGENTS.md` pour la convergence des VM existantes et futures : - cycle de vie des VM ; - distinction service central et intégration cliente ; - groupes d'inventaire par intégration ; - séparation des variables de template, conformité et services. - Ajout d'un `Makefile` comme interface d'exploitation courante : - validation ; - syntax-checks ; - préparation, vérification et nettoyage protégé du template ; - socle et durcissement des VM Debian. - Durcissement SSH du template dès la construction : - accès par clé publique obligatoire ; - authentification par mot de passe désactivée ; - forwarding et tunnels SSH désactivés par défaut ; - limites de tentatives, sessions et démarrages SSH resserrées. ### Modifié - Renforcement attendu de `CLAUDE.md` pour rappeler que `AGENTS.md` est la source d’autorité principale. - Clarification du comportement attendu de Claude Code : - lire l’existant avant modification ; - vérifier `git status --short` ; - ne pas faire de régénération massive sans demande explicite ; - valider les playbooks touchés ; - signaler les tests non exécutés ; - mettre à jour `CHANGELOG.md` si pertinent. - Migration des variables de rôles vers des préfixes propres à chaque rôle pour respecter `ansible-lint`. - Mise à jour de la variable de confirmation du nettoyage final : - `template_cleanup_confirm`. - Correction de la structure du `CHANGELOG.md` pour retirer le titre dupliqué. - Simplification ciblée de l'arborescence `roles/` : - retrait des doublons non utilisés sous `roles/base/` ; - retrait des doublons non utilisés sous `roles/security/` ; - retrait des doublons non utilisés sous `roles/vm_template/`. - Ajout d'un renvoi depuis la procédure manuelle vers la justification du golden template. - Séparation documentaire et opérationnelle entre variables de template et variables de conformité. - Extension du playbook de groupe `playbooks/groupes/serveurs_debian.yml` pour maintenir le socle commun des VM Debian déployées. - Mise à jour de la documentation pour exiger un `ciuser` cloud-init avec clé publique avant l'exécution d'Ansible. - Déplacement des listes de paquets communes dans les defaults des rôles `common_packages` et `hardening_packages`. - Déplacement des variables de construction du template dans `inventories/lab/group_vars/modeles_vm.yml`. - Déplacement des variables de conformité Debian dans `inventories/production/group_vars/serveurs_debian.yml`. - Ciblage du playbook de durcissement sur `serveurs_debian` au lieu de `all`. - Renforcement du playbook de vérification du modèle doré. ### Corrigé - Vérification des rôles contenant `notify`. - Confirmation des handlers SSH requis dans les rôles concernés : - `roles/ssh_baseline/handlers/main.yml` ; - `roles/ssh_hardening/handlers/main.yml`. ### Validé - Vérification que chaque `notify` du template Debian 13 Proxmox pointe vers un handler existant. - Relance du playbook de préparation du template Debian 13 Proxmox. - Nettoyage final non lancé.