From b33e21c0e4caa2f059df564b1b1e5c0e8804bc24 Mon Sep 17 00:00:00 2001 From: Daniel Allaire Date: Wed, 24 Jun 2026 11:56:20 -0400 Subject: [PATCH] Accueil d'un nouvel hebergeur : QUICKSTART, README reoriente, garde-fou Avant un test a froid par un sysadmin etranger, on corrige les blocages d'accueil (mauvaises raisons d'echouer) : - QUICKSTART.md : parcours lineaire zero -> ecosysteme deploye sur Proxmox (modele -> instance -> config -> golden template -> instancier -> cloner-vm -> deployer), honnete sur prerequis et seam creation-de-VM. - README : reoriente "moteur generique pour un hebergeur" (plus "infra Chezlepro"), pointeur QUICKSTART. - Makefile : garde-fou _instance-requise (message utile + liste des modeles si l'instance manque, au lieu d'un faux "valide" silencieux) ; make aide route vers QUICKSTART. Co-Authored-By: Claude Opus 4.8 --- CHANGELOG.md | 1 + Makefile | 25 +++++++++--- QUICKSTART.md | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 12 ++++-- 4 files changed, 133 insertions(+), 9 deletions(-) create mode 100644 QUICKSTART.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 45b3769..9a3a6db 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ - **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é +- **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). diff --git a/Makefile b/Makefile index a15e7b8..0d54410 100644 --- a/Makefile +++ b/Makefile @@ -78,9 +78,22 @@ ansible-runtime: @mkdir -p "$(ANSIBLE_LOCAL_TEMP)" @mkdir -p "$(ANSIBLE_SSH_CONTROL_PATH_DIR)" +.PHONY: _instance-requise +_instance-requise: + @if [[ ! -f "$(SETOPS_INSTANCE)/plan/serveurs.yml" ]]; then \ + printf '%s\n' "Aucune instance configuree : '$(SETOPS_INSTANCE)/plan' introuvable."; \ + printf '%s\n' "Demarre avec QUICKSTART.md. En bref :"; \ + printf '%s\n' " cp -r exemples/modeles/ ../mon-instance && ln -s ../mon-instance instance"; \ + printf '%s\n' " modeles disponibles : $$(ls exemples/modeles 2>/dev/null | grep -v '\.md' | tr '\n' ' ')"; \ + exit 2; \ + fi + .PHONY: aide aide: - @printf '%s\n' 'Set-OPS' + @printf '%s\n' 'Set-OPS — moteur d ecosystemes numeriques souverains' + @printf '%s\n' '' + @printf '%s\n' 'Nouveau ? -> QUICKSTART.md (de zero a ton ecosysteme sur Proxmox)' + @printf '%s\n' 'Flux: editer le plan -> make instancier -> make instancier-appliquer -> make deployer' @printf '%s\n' '' @printf '%s\n' 'VM' @printf '%s\n' ' Creer une VM complete:' @@ -183,7 +196,7 @@ inventaire: inventaire-production config: python3 scripts/config_proxmox.py -inventaire-ui: +inventaire-ui: _instance-requise python3 scripts/inventory_gui.py --inventaire $(FICHIER_INVENTAIRE) hote-ajouter: ansible-runtime @@ -232,7 +245,7 @@ appliquer: ansible-runtime python3 scripts/inventory_host.py --inventaire $(INVENTAIRE_PRODUCTION) --dependances $(FICHIER_DEPENDANCES) verifier-dependances-groupe --groupe $(GROUPE) ansible-playbook -i $(INVENTAIRE_PRODUCTION) "$(DOSSIER_PLAYBOOKS_GROUPES)/$(GROUPE).yml" --limit '$(GROUPE):&$(GROUPE_HOTES_ACTIFS)' -deployer: +deployer: _instance-requise @set -e; \ if [[ -z "$(HOTE)" ]]; then \ printf '%s\n' 'Refus: relancer avec HOTE=nom_hote.'; \ @@ -366,7 +379,7 @@ creer-vm: $(MAKE) cloner-vm HOTE="$(HOTE)" VMID_MODELE="$(VMID_MODELE)" VMID="$(VMID)" NOEUD_PROXMOX="$(NOEUD_PROXMOX)" STOCKAGE_PROXMOX="$(STOCKAGE_PROXMOX)" FORMAT_DISQUE="$(FORMAT_DISQUE)" TAILLE_DISQUE="$(TAILLE_DISQUE)" DISQUE_PROXMOX="$(DISQUE_PROXMOX)" ADRESSE_IP="$(ADRESSE_IP)" CIDR="$(CIDR)" PASSERELLE="$(PASSERELLE)" DNS="$(DNS)" DHCP="$(DHCP)" CIUSER="$(CIUSER)" CLE_SSH_PUBLIQUE="$(CLE_SSH_PUBLIQUE)" PONT_PROXMOX="$(PONT_PROXMOX)" VLAN="$(VLAN)" DEMARRER="$(DEMARRER)" CLONE_COMPLET="$(CLONE_COMPLET)" $(MAKE) hote-ajouter HOTE="$(HOTE)" ADRESSE_IP="$(ADRESSE_IP)" VMID="$(VMID)" GROUPES="$(GROUPES)" FICHIER_INVENTAIRE="$(FICHIER_INVENTAIRE)" -inventaire-verifier: ansible-runtime +inventaire-verifier: ansible-runtime _instance-requise ansible-inventory -i $(INVENTAIRE_LAB) --list > /dev/null ansible-inventory -i $(INVENTAIRE_PRODUCTION) --list > /dev/null python3 scripts/inventory_host.py --inventaire $(INVENTAIRE_PRODUCTION) verifier-playbooks --dossier-playbooks $(DOSSIER_PLAYBOOKS_GROUPES) @@ -388,11 +401,11 @@ serveurs-bootstrap: python3 scripts/serveurs.py bootstrap .PHONY: instancier instancier-appliquer -instancier: +instancier: _instance-requise python3 scripts/instancier.py generer python3 scripts/instancier.py comparer -instancier-appliquer: +instancier-appliquer: _instance-requise python3 scripts/instancier.py appliquer bases: diff --git a/QUICKSTART.md b/QUICKSTART.md new file mode 100644 index 0000000..456d05b --- /dev/null +++ b/QUICKSTART.md @@ -0,0 +1,104 @@ +# Démarrage rapide — de zéro à ton écosystème souverain + +Tu débarques avec une **grappe Proxmox vierge** et tu veux monter ton écosystème +numérique. Voici le chemin, de bout en bout. Set-OPS est le **moteur** ; tu vas +créer **ton instance** à partir d'un modèle, puis déployer. + +> Concepts en 10 s : tu **décris un plan** (quelles VM, quels services), le moteur +> **génère l'inventaire**, et Ansible **déploie**. Tu n'édites jamais l'inventaire +> à la main. Détails : `docs/plan-et-generation.md`. + +## 0. Prérequis (à toi de fournir) +- une **grappe Proxmox** où tu es admin (API activée) ; +- une machine de pilotage Linux avec **Ansible**, **Python 3**, **make**, `git` + (et `node` pour le garde-fou JS du GUI, optionnel) ; +- un **token API Proxmox** ; +- une **paire de clés SSH** (la publique ira dans les VM via cloud-init) ; +- un **mot de passe Ansible Vault** (pour chiffrer tes secrets). + +## 1. Cloner le moteur +```bash +git clone Set-OPS && cd Set-OPS +``` + +## 2. Choisir un modèle et créer ton instance +Les modèles sont dans `exemples/modeles/` (voir leur README). Choisis selon ton offre : +`socle`, `presence-web`, `forge`, `identite`, `observabilite`, `integral`. + +```bash +cp -r exemples/modeles/presence-web ../mon-instance # ton instance, ailleurs +ln -s ../mon-instance instance # le moteur la trouve via ce lien +``` +*(Alternative au symlink : `export SETOPS_INSTANCE=../mon-instance`.)* + +## 3. Renseigner ton instance (« tes couleurs ») +- `instance/inventories/production/group_vars/all.yml` → **`domaine_interne`** (ex. `monorg.internal`) ; +- `instance/plan/nomenclature.yml` → ton **supernet** (ex. `10.20.0.0/16`) ; +- `instance/plan/domaines.yml` → ton **domaine public** ; +- `instance/plan/serveurs.yml` → **placement Proxmox** (nœud, stockage, disque, mémoire, cœurs). + +Tu peux aussi le faire dans le GUI plus tard (`make inventaire-ui`). + +## 4. Configurer Proxmox et tes secrets +```bash +make config # renseigne API host/user/port, nœud, stockage, VMID du template... +``` +Place ton **token API** et tes secrets dans le Vault de l'instance +(`instance/inventories/lab/group_vars/proxmox.vault.yml`, à partir du `.example`, +chiffré avec `ansible-vault`). Exporte ton mot de passe Vault, ex. : +```bash +export ANSIBLE_VAULT_PASSWORD_FILE=~/.config/setops-vault-pass +``` + +## 5. Construire le golden template Debian 13 (UNE seule fois) +Une grappe vierge n'a aucun template. Crée une VM **Debian 13 vanille**, rends-la +joignable par Ansible, puis : +```bash +make preparer-modele # socle + durcissement + cloud-init + qemu-guest-agent... +make verifier-modele +make nettoyer-modele CONFIRMER=true +``` +Convertis ensuite la VM en **template Proxmox** nommé `modele-debian13` (le nom de +clone source par défaut). Détails et procédure : `docs/vm-lifecycle.md` et +`docs/procedure-template-debian13-proxmox.md`. + +## 6. Générer ton inventaire depuis le plan +```bash +make instancier # montre ce que le plan produit (diff) +make instancier-appliquer FORCE=1 # 1re génération : écrit instance/inventories/production/hosts.yml +``` +Tes hôtes sont là, en état `planifie`. `make serveurs` te montre leurs VMID/IP dérivés. + +## 7. Créer les VM (clone du template + cloud-init) +Pour chaque hôte, avec ses valeurs dérivées (`make serveurs`) : +```bash +make cloner-vm HOTE=infra-dns-01 VMID= ADRESSE_IP= VLAN= PASSERELLE= +``` +*(Les valeurs de nœud/stockage/template viennent de `make config`. Note honnête : +à ce stade la création de VM prend ces paramètres par hôte ; l'intégration +complète « plan → création » est la prochaine frontière.)* + +## 8. Activer puis déployer +Passe l'hôte en `etat: actif` dans `instance/plan/serveurs.yml`, régénère, déploie : +```bash +make instancier-appliquer +make deployer HOTE=infra-dns-01 # configure l'hôte selon ses groupes +# ou, par couche : +make deployer-groupe GROUPE=serveur_postgresql +``` +Les déploiements de groupe ne ciblent **que** les hôtes actifs. + +## 9. Ensuite : tu vis dans le plan +Édite le plan (GUI `make inventaire-ui`, ou les registres `instance/plan/`), +`make instancier-appliquer`, `make deployer`. Tu ne touches jamais `hosts.yml`. + +## Valider à tout moment +```bash +make inventaire-verifier # registres + inventaire + garde-fous +make verifier # + ansible-lint + --syntax-check +``` + +--- + +Ordre de mise en place des services : `docs/catalogue-services.md`. Modèle, +registres et règle d'or : `docs/plan-et-generation.md` et `AGENTS.md`. diff --git a/README.md b/README.md index 50a1548..f98d336 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,14 @@ -# Set-OPS — Votre artisan numérique +# Set-OPS — moteur d'écosystèmes numériques souverains -Dépôt Ansible central pour construire, configurer, maintenir et documenter les systèmes de Chezlepro Inc. +**Set-OPS est un moteur Ansible générique** qui permet à un hébergeur de **construire et exploiter un écosystème numérique souverain** — DNS interne, AC/PKI, identité (LDAP + SSO), relais courriel, bases de données, observabilité, applications — sur sa propre grappe **Proxmox**, à partir d'un **plan déclaratif**. -## Mission +Le dépôt est le **moteur** (générique, partageable). Chaque déploiement réel est une **instance** (le plan + l'inventaire d'un hébergeur, dans son propre dépôt). Chezlepro en est une ; tu crées la tienne à partir d'un **modèle prêt à déployer** (`exemples/modeles/`). + +> 👉 **Tu débarques avec une grappe Proxmox et tu veux monter ton écosystème ? Commence par [`QUICKSTART.md`](QUICKSTART.md).** + +--- + +## Mission (la vision derrière l'outil) `Set-OPS` ne se limite plus à l'exploitation : il **définit et construit l'écosystème numérique souverain de Chezlepro Inc.** — une infrastructure interne auto-suffisante, sans dépendance SaaS, décrite en code et pilotée par des registres machine-lisibles qui font office de **source unique de vérité** (`instance/plan/serveurs.yml`, `instance/plan/applications.yml`, `instance/plan/bases-donnees.yml`, `instance/plan/domaines.yml`, `instance/plan/nomenclature.yml`, `docs/dependances-groupes.yml`).