Decouplage moteur/instance Phase 2b : sortir l'inventaire

L'inventaire (hotes generes, group_vars, vault) quitte inventories/ pour
instance/inventories/. Suivent : ansible.cfg, Makefile (export
SETOPS_INSTANCE ?= instance + chemins derives), scripts (INSTANCE/),
config_proxmox.py, .gitignore. Docs primaires (AGENTS/README/
plan-et-generation/architecture) refletent le layout instance/.

Non destructif : diff vide, ansible-lint 0 echec, make inventaire-verifier
OK. (Docs secondaires a rafraichir ; Phase 3 : deux depots.)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Daniel Allaire 2026-06-24 09:16:18 -04:00
parent 17f65efb18
commit 3b7f3098f2
36 changed files with 42 additions and 39 deletions

2
.gitignore vendored
View file

@ -1,6 +1,6 @@
*.retry *.retry
# Inventaire genere depuis le plan (artefact, make instancier ; pas une source). # Inventaire genere depuis le plan (artefact, make instancier ; pas une source).
inventories/*/hosts.genere.yml instance/inventories/*/hosts.genere.yml
.vault-pass .vault-pass
facts_cache/ facts_cache/
.ansible/ .ansible/

View file

@ -27,7 +27,7 @@ Piliers de lécosystème :
Propriétés visées, avec leurs nuances honnêtes : Propriétés visées, avec leurs nuances honnêtes :
- **Souverain / auto-suffisant** : cest lobjectif. Aucune dépendance à un service externe pour la confiance, lidentité, le nom ou la communication. Cela justifie le choix de construire plutôt quassembler des SaaS. - **Souverain / auto-suffisant** : cest lobjectif. Aucune dépendance à un service externe pour la confiance, lidentité, le nom ou la communication. Cela justifie le choix de construire plutôt quassembler des SaaS.
- **Déclaratif et convergent** : létat voulu est décrit dans des registres machine-lisibles (`docs/nomenclature.yml`, `docs/dependances-groupes.yml`, `docs/bases-donnees.yml`) et appliqué par les groupes Ansible. Ces registres sont la **source unique de vérité**. - **Déclaratif et convergent** : létat voulu est décrit dans des registres machine-lisibles (`instance/plan/nomenclature.yml`, `docs/dependances-groupes.yml`, `instance/plan/bases-donnees.yml`) et appliqué par les groupes Ansible. Ces registres sont la **source unique de vérité**.
- **Pas (encore) auto-réparé** : la convergence est pilotée par lopérateur (GUI / CLI / `make`), pas une boucle fermée dauto-remédiation. - **Pas (encore) auto-réparé** : la convergence est pilotée par lopérateur (GUI / CLI / `make`), pas une boucle fermée dauto-remédiation.
- **Définition avant déploiement** : une grande partie est planifiée et validée (`--syntax-check`, `ansible-lint`) mais pas encore exécutée contre des VM réelles. Ne jamais présenter un rôle non déployé comme « en production ». - **Définition avant déploiement** : une grande partie est planifiée et validée (`--syntax-check`, `ansible-lint`) mais pas encore exécutée contre des VM réelles. Ne jamais présenter un rôle non déployé comme « en production ».
@ -40,10 +40,10 @@ Conséquence pour le travail : préserver la discipline qui tient lensemble
`Set-OPS` se pilote par un **plan**, pas par lédition directe de linventaire. `Set-OPS` se pilote par un **plan**, pas par lédition directe de linventaire.
Linventaire Ansible est **généré** depuis le plan. Linventaire Ansible est **généré** depuis le plan.
**RÈGLE DOR : `inventories/production/hosts.yml` est un artefact GÉNÉRÉ. Ne jamais léditer à la main.** On édite le *plan*, puis on régénère. **RÈGLE DOR : `instance/inventories/production/hosts.yml` est un artefact GÉNÉRÉ. Ne jamais léditer à la main.** On édite le *plan*, puis on régénère.
- L**application** est lentité pivot ; le **groupe** Ansible nest quune capacité (le rôle appliqué), plus une cible de liaison. - L**application** est lentité pivot ; le **groupe** Ansible nest quune capacité (le rôle appliqué), plus une cible de liaison.
- Le plan vit dans des registres machine-lisibles : `docs/serveurs.yml` (les VM), `docs/applications.yml` (les services et leurs liens `requiert`/`utilise`/`expose`), `docs/bases-donnees.yml`, `docs/domaines.yml`, `docs/nomenclature.yml`. - Le plan vit dans des registres machine-lisibles : `instance/plan/serveurs.yml` (les VM), `instance/plan/applications.yml` (les services et leurs liens `requiert`/`utilise`/`expose`), `instance/plan/bases-donnees.yml`, `instance/plan/domaines.yml`, `instance/plan/nomenclature.yml`.
- Génération : `make instancier` (génère + diff sémantique), `make instancier-appliquer` (régénère `hosts.yml`, refuse si le diff nest pas vide — `FORCE=1` pour un changement intentionnel). - Génération : `make instancier` (génère + diff sémantique), `make instancier-appliquer` (régénère `hosts.yml`, refuse si le diff nest pas vide — `FORCE=1` pour un changement intentionnel).
- Flux : **éditer le plan → `make instancier` (revoir le diff) → `make instancier-appliquer` → déployer**. Via le GUI : vues **Serveurs** et **Applications**, puis « Appliquer le plan » (la vue Inventaire est en lecture seule). - Flux : **éditer le plan → `make instancier` (revoir le diff) → `make instancier-appliquer` → déployer**. Via le GUI : vues **Serveurs** et **Applications**, puis « Appliquer le plan » (la vue Inventaire est en lecture seule).
- VMID / IP / VLAN / passerelle sont **dérivés** de la `fonction` via la nomenclature ; les groupes dune VM sont dérivés (socle + services des applications + intégrations + état). - VMID / IP / VLAN / passerelle sont **dérivés** de la `fonction` via la nomenclature ; les groupes dune VM sont dérivés (socle + services des applications + intégrations + état).
@ -159,7 +159,7 @@ Avant de proposer un changement comme terminé, vérifier au minimum la syntaxe
Exemple pour le template Debian 13 Proxmox : Exemple pour le template Debian 13 Proxmox :
```bash ```bash
ansible-playbook -i inventories/lab/hosts.yml playbooks/modeles_vm/debian13_proxmox_preparer.yml --syntax-check ansible-playbook -i instance/inventories/lab/hosts.yml playbooks/modeles_vm/debian13_proxmox_preparer.yml --syntax-check
``` ```
Pour un autre playbook, remplacer le chemin par le playbook concerné. Pour un autre playbook, remplacer le chemin par le playbook concerné.
@ -595,7 +595,7 @@ Le nettoyage final avant conversion en template doit être protégé par une con
Exemple : Exemple :
```bash ```bash
ansible-playbook -i inventories/lab/hosts.yml playbooks/modeles_vm/debian13_proxmox_nettoyer.yml -e template_cleanup_confirm=true ansible-playbook -i instance/inventories/lab/hosts.yml playbooks/modeles_vm/debian13_proxmox_nettoyer.yml -e template_cleanup_confirm=true
``` ```
Le nettoyage peut inclure : Le nettoyage peut inclure :

View file

@ -3,6 +3,7 @@
## 2026-06-23 ## 2026-06-23
### Modifié ### Modifié
- **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 `<dépôt>/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 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 `<dépôt>/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 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.)* - **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.)*

View file

@ -5,8 +5,9 @@ export ANSIBLE_LOCAL_TEMP ?= $(CURDIR)/.ansible/tmp
export ANSIBLE_SSH_CONTROL_PATH_DIR ?= $(CURDIR)/.ansible/cp export ANSIBLE_SSH_CONTROL_PATH_DIR ?= $(CURDIR)/.ansible/cp
export ANSIBLE_SSH_ARGS ?= -F /dev/null -o ControlMaster=no export ANSIBLE_SSH_ARGS ?= -F /dev/null -o ControlMaster=no
INVENTAIRE_LAB ?= inventories/lab/hosts.yml export SETOPS_INSTANCE ?= instance
INVENTAIRE_PRODUCTION ?= inventories/production/hosts.yml INVENTAIRE_LAB ?= $(SETOPS_INSTANCE)/inventories/lab/hosts.yml
INVENTAIRE_PRODUCTION ?= $(SETOPS_INSTANCE)/inventories/production/hosts.yml
FICHIER_INVENTAIRE ?= $(INVENTAIRE_PRODUCTION) FICHIER_INVENTAIRE ?= $(INVENTAIRE_PRODUCTION)
FICHIER_DEPENDANCES ?= docs/dependances-groupes.yml FICHIER_DEPENDANCES ?= docs/dependances-groupes.yml
GROUPE_MODELE ?= modeles_vm GROUPE_MODELE ?= modeles_vm
@ -121,7 +122,7 @@ aide:
@printf '%s\n' ' Graphe de production:' @printf '%s\n' ' Graphe de production:'
@printf '%s\n' ' make inventaire' @printf '%s\n' ' make inventaire'
@printf '%s\n' ' Graphe explicite:' @printf '%s\n' ' Graphe explicite:'
@printf '%s\n' ' make inventaire-graphe FICHIER_INVENTAIRE=inventories/production/hosts.yml' @printf '%s\n' ' make inventaire-graphe FICHIER_INVENTAIRE=$(SETOPS_INSTANCE)/inventories/production/hosts.yml'
@printf '%s\n' ' Verifier les inventaires:' @printf '%s\n' ' Verifier les inventaires:'
@printf '%s\n' ' make inventaire-verifier' @printf '%s\n' ' make inventaire-verifier'
@printf '%s\n' ' Lister les donnees brutes:' @printf '%s\n' ' Lister les donnees brutes:'
@ -144,7 +145,7 @@ aide:
@printf '%s\n' 'Variables frequentes' @printf '%s\n' 'Variables frequentes'
@printf '%s\n' ' HOTE=web-frontal-01 GROUPE=serveur_debian GROUPES="serveur_debian serveur_durci"' @printf '%s\n' ' HOTE=web-frontal-01 GROUPE=serveur_debian GROUPES="serveur_debian serveur_durci"'
@printf '%s\n' ' VMID=95301 VLAN=15 ADRESSE_IP=10.1.15.31 PASSERELLE=10.1.15.1' @printf '%s\n' ' VMID=95301 VLAN=15 ADRESSE_IP=10.1.15.31 PASSERELLE=10.1.15.1'
@printf '%s\n' ' FICHIER_INVENTAIRE=inventories/production/hosts.yml FICHIER_DEPENDANCES=docs/dependances-groupes.yml CONFIRMER=true' @printf '%s\n' ' FICHIER_INVENTAIRE=$(SETOPS_INSTANCE)/inventories/production/hosts.yml FICHIER_DEPENDANCES=docs/dependances-groupes.yml CONFIRMER=true'
.PHONY: lint .PHONY: lint
lint: ansible-runtime lint: ansible-runtime
@ -244,7 +245,7 @@ deployer:
printf '%s\n' 'Refus: aucun playbook applicable pour HOTE=$(HOTE).'; \ printf '%s\n' 'Refus: aucun playbook applicable pour HOTE=$(HOTE).'; \
exit 2; \ exit 2; \
fi; \ fi; \
vault_chiffre="$$(grep -rlsIF '$$ANSIBLE_VAULT' inventories/production/group_vars 2>/dev/null | head -1 || true)"; \ vault_chiffre="$$(grep -rlsIF '$$ANSIBLE_VAULT' $(SETOPS_INSTANCE)/inventories/production/group_vars 2>/dev/null | head -1 || true)"; \
if [[ -n "$$vault_chiffre" && -z "$${ANSIBLE_VAULT_PASSWORD_FILE:-}" ]]; then \ if [[ -n "$$vault_chiffre" && -z "$${ANSIBLE_VAULT_PASSWORD_FILE:-}" ]]; then \
if [[ -t 0 ]]; then \ if [[ -t 0 ]]; then \
read -r -s -p 'Mot de passe du vault Ansible: ' mdp; echo; \ read -r -s -p 'Mot de passe du vault Ansible: ' mdp; echo; \
@ -284,7 +285,7 @@ verifier-deploiement: ansible-runtime
printf '%s\n' 'Refus: aucun playbook applicable pour HOTE=$(HOTE).'; \ printf '%s\n' 'Refus: aucun playbook applicable pour HOTE=$(HOTE).'; \
exit 2; \ exit 2; \
fi; \ fi; \
vault_chiffre="$$(grep -rlsIF '$$ANSIBLE_VAULT' inventories/production/group_vars 2>/dev/null | head -1 || true)"; \ vault_chiffre="$$(grep -rlsIF '$$ANSIBLE_VAULT' $(SETOPS_INSTANCE)/inventories/production/group_vars 2>/dev/null | head -1 || true)"; \
if [[ -n "$$vault_chiffre" && -z "$${ANSIBLE_VAULT_PASSWORD_FILE:-}" ]]; then \ if [[ -n "$$vault_chiffre" && -z "$${ANSIBLE_VAULT_PASSWORD_FILE:-}" ]]; then \
if [[ -t 0 ]]; then \ if [[ -t 0 ]]; then \
read -r -s -p 'Mot de passe du vault Ansible: ' mdp; echo; \ read -r -s -p 'Mot de passe du vault Ansible: ' mdp; echo; \
@ -344,7 +345,7 @@ cloner-vm: ansible-runtime
extra_vars+=( -e proxmox_clone_vlan="$(VLAN)" ); \ extra_vars+=( -e proxmox_clone_vlan="$(VLAN)" ); \
[[ -n "$(DEMARRER)" ]] && extra_vars+=( -e proxmox_clone_demarrer="$(DEMARRER)" ); \ [[ -n "$(DEMARRER)" ]] && extra_vars+=( -e proxmox_clone_demarrer="$(DEMARRER)" ); \
vault_args=(); \ vault_args=(); \
vault_file="inventories/lab/group_vars/proxmox.vault.yml"; \ vault_file="$(SETOPS_INSTANCE)/inventories/lab/group_vars/proxmox.vault.yml"; \
if [[ -f "$$vault_file" ]]; then \ if [[ -f "$$vault_file" ]]; then \
read -r premiere_ligne < "$$vault_file" || true; \ read -r premiere_ligne < "$$vault_file" || true; \
case "$$premiere_ligne" in \ case "$$premiere_ligne" in \

View file

@ -4,7 +4,7 @@ Dépôt Ansible central pour construire, configurer, maintenir et documenter les
## Mission ## Mission
`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é** (`docs/serveurs.yml`, `docs/applications.yml`, `docs/bases-donnees.yml`, `docs/domaines.yml`, `docs/nomenclature.yml`, `docs/dependances-groupes.yml`). `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`).
Piliers de l'écosystème : Piliers de l'écosystème :
@ -23,13 +23,13 @@ Cadre et règles d'autorité : voir `AGENTS.md` (section « Mission et identité
## Le plan : on édite, l'inventaire se génère ## Le plan : on édite, l'inventaire se génère
`Set-OPS` se pilote par un **plan**, pas par l'édition directe de l'inventaire. `Set-OPS` se pilote par un **plan**, pas par l'édition directe de l'inventaire.
`inventories/production/hosts.yml` est **généré** depuis le plan — **ne pas l'éditer à la main**. `instance/inventories/production/hosts.yml` est **généré** depuis le plan — **ne pas l'éditer à la main**.
``` ```
éditer le PLAN → make instancier (revoir le diff) → make instancier-appliquer → make deployer éditer le PLAN → make instancier (revoir le diff) → make instancier-appliquer → make deployer
``` ```
- **Plan** : `docs/serveurs.yml` (les VM), `docs/applications.yml` (les services et leurs liens), `docs/bases-donnees.yml`, `docs/domaines.yml`, dérivés via `docs/nomenclature.yml`. - **Plan** : `instance/plan/serveurs.yml` (les VM), `instance/plan/applications.yml` (les services et leurs liens), `instance/plan/bases-donnees.yml`, `instance/plan/domaines.yml`, dérivés via `instance/plan/nomenclature.yml`.
- **GUI** (`make inventaire-ui`) : vues **Serveurs** et **Applications** pour éditer, puis « Appliquer le plan » ; la vue **Inventaire** est en lecture seule. - **GUI** (`make inventaire-ui`) : vues **Serveurs** et **Applications** pour éditer, puis « Appliquer le plan » ; la vue **Inventaire** est en lecture seule.
- VMID / IP / VLAN sont **dérivés** de la `fonction` ; les groupes d'une VM sont dérivés des applications qui y tournent. - VMID / IP / VLAN sont **dérivés** de la `fonction` ; les groupes d'une VM sont dérivés des applications qui y tournent.
@ -98,13 +98,13 @@ make inventaire-ui
Planifier une VM passe désormais par le **plan**, pas par l'édition de l'inventaire : Planifier une VM passe désormais par le **plan**, pas par l'édition de l'inventaire :
1. déclarer la VM dans `docs/serveurs.yml` (vue **Serveurs** du GUI, ou `make serveurs`) — `fonction`, `etat`, placement ; VMID/IP/VLAN sont dérivés ; 1. déclarer la VM dans `instance/plan/serveurs.yml` (vue **Serveurs** du GUI, ou `make serveurs`) — `fonction`, `etat`, placement ; VMID/IP/VLAN sont dérivés ;
2. déclarer les services qui y tournent dans `docs/applications.yml` (vue **Applications**) ; 2. déclarer les services qui y tournent dans `instance/plan/applications.yml` (vue **Applications**) ;
3. régénérer l'inventaire : 3. régénérer l'inventaire :
```bash ```bash
make instancier # génère + diff sémantique (que va-t-il changer ?) make instancier # génère + diff sémantique (que va-t-il changer ?)
make instancier-appliquer # régénère inventories/production/hosts.yml make instancier-appliquer # régénère instance/inventories/production/hosts.yml
``` ```
Les anciennes commandes `make hote-planifier` / `hote-ajouter` / `hote-groupes` éditaient l'inventaire **directement** ; elles sont **supplantées** par le plan (l'inventaire est généré, ne pas l'éditer à la main). Les anciennes commandes `make hote-planifier` / `hote-ajouter` / `hote-groupes` éditaient l'inventaire **directement** ; elles sont **supplantées** par le plan (l'inventaire est généré, ne pas l'éditer à la main).

View file

@ -1,5 +1,5 @@
[defaults] [defaults]
inventory = inventories/lab/hosts.yml inventory = instance/inventories/lab/hosts.yml
roles_path = roles roles_path = roles
filter_plugins = filter_plugins filter_plugins = filter_plugins
interpreter_python = auto_silent interpreter_python = auto_silent

View file

@ -1,7 +1,7 @@
# Architecture Set-OPS # Architecture Set-OPS
Set-OPS définit et construit l'écosystème numérique souverain de Chezlepro. Il se Set-OPS définit et construit l'écosystème numérique souverain de Chezlepro. Il se
pilote par un **plan** : l'inventaire Ansible (`inventories/production/hosts.yml`) pilote par un **plan** : l'inventaire Ansible (`instance/inventories/production/hosts.yml`)
est **généré** depuis le plan, pas édité à la main. est **généré** depuis le plan, pas édité à la main.
- Modèle, registres, commandes et flux de travail : **`docs/plan-et-generation.md`**. - Modèle, registres, commandes et flux de travail : **`docs/plan-et-generation.md`**.
@ -10,11 +10,11 @@ est **généré** depuis le plan, pas édité à la main.
## Entités du plan ## Entités du plan
```text ```text
serveur (VM) docs/serveurs.yml fonction, état, placement, intégrations serveur (VM) instance/plan/serveurs.yml fonction, état, placement, intégrations
application docs/applications.yml groupe (rôle), hôte, port, requiert, expose application instance/plan/applications.yml groupe (rôle), hôte, port, requiert, expose
base docs/bases-donnees.yml serveur de BD, base, propriétaire, secret (Vault), portée base instance/plan/bases-donnees.yml serveur de BD, base, propriétaire, secret (Vault), portée
domaine (DNS) docs/domaines.yml zone publique, autorité, edge domaine (DNS) instance/plan/domaines.yml zone publique, autorité, edge
nomenclature docs/nomenclature.yml fonctions -> VMID / VLAN / IP (dérivés) nomenclature instance/plan/nomenclature.yml fonctions -> VMID / VLAN / IP (dérivés)
``` ```
L'**application** est l'entité pivot ; le **groupe** Ansible n'est qu'une capacité L'**application** est l'entité pivot ; le **groupe** Ansible n'est qu'une capacité
@ -33,7 +33,7 @@ Les valeurs communes aux rôles doivent rester dans les defaults des rôles quan
Les groupes opérationnels de l'inventaire doivent correspondre à un playbook homonyme : Les groupes opérationnels de l'inventaire doivent correspondre à un playbook homonyme :
```text ```text
inventories/production/hosts.yml instance/inventories/production/hosts.yml
serveur_debian serveur_debian
playbooks/groupes/serveur_debian.yml playbooks/groupes/serveur_debian.yml

View file

@ -5,7 +5,7 @@ l'inventaire Ansible en est **généré**. Le dépôt est la définition ; chaqu
est une instance. Ce document décrit le modèle, les registres, les commandes et est une instance. Ce document décrit le modèle, les registres, les commandes et
le flux de travail. le flux de travail.
> Règle d'or : **`inventories/production/hosts.yml` est GÉNÉRÉ. Ne jamais l'éditer > Règle d'or : **`instance/inventories/production/hosts.yml` est GÉNÉRÉ. Ne jamais l'éditer
> à la main.** On édite le *plan* puis on régénère (`make instancier-appliquer`). > à la main.** On édite le *plan* puis on régénère (`make instancier-appliquer`).
--- ---
@ -144,8 +144,8 @@ itèrent ainsi sur les applications de l'hôte et résolvent leurs DSN.
Pour (re)construire le plan depuis un inventaire existant : Pour (re)construire le plan depuis un inventaire existant :
```bash ```bash
make serveurs-bootstrap # VM -> docs/serveurs.yml (fonction/état/placement/integrations) make serveurs-bootstrap # VM -> instance/plan/serveurs.yml (fonction/état/placement/integrations)
make applications-bootstrap # services serveurs_* (hors socle) -> docs/applications.yml make applications-bootstrap # services serveurs_* (hors socle) -> instance/plan/applications.yml
make instancier # vérifier le diff vide make instancier # vérifier le diff vide
``` ```

View file

@ -26,7 +26,7 @@ INSTANCE = Path(os.environ.get("SETOPS_INSTANCE") or (RACINE / "instance"))
FICHIER = INSTANCE / "plan/applications.yml" FICHIER = INSTANCE / "plan/applications.yml"
FICHIER_BASES = INSTANCE / "plan/bases-donnees.yml" FICHIER_BASES = INSTANCE / "plan/bases-donnees.yml"
FICHIER_DOMAINES = INSTANCE / "plan/domaines.yml" FICHIER_DOMAINES = INSTANCE / "plan/domaines.yml"
INVENTAIRE = RACINE / "inventories/production/hosts.yml" INVENTAIRE = INSTANCE / "inventories/production/hosts.yml"
# Groupes 'serveurs_*' qui sont des capacites de SOCLE (sur toutes les VM), # Groupes 'serveurs_*' qui sont des capacites de SOCLE (sur toutes les VM),
# pas des applications a part entiere. # pas des applications a part entiere.

View file

@ -13,8 +13,9 @@ import yaml
RACINE = Path(__file__).resolve().parents[1] RACINE = Path(__file__).resolve().parents[1]
FICHIER_PROXMOX = RACINE / "inventories/lab/group_vars/proxmox.yml" INSTANCE = Path(os.environ.get("SETOPS_INSTANCE") or (RACINE / "instance"))
FICHIER_VAULT = RACINE / "inventories/lab/group_vars/proxmox.vault.yml" FICHIER_PROXMOX = INSTANCE / "inventories/lab/group_vars/proxmox.yml"
FICHIER_VAULT = INSTANCE / "inventories/lab/group_vars/proxmox.vault.yml"
VALEURS_DEFAUT = { VALEURS_DEFAUT = {

View file

@ -1,7 +1,7 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
"""Generateur d'inventaire Set-OPS (Phase 3) : plan -> hosts.yml. """Generateur d'inventaire Set-OPS (Phase 3) : plan -> hosts.yml.
NON destructif : ecrit dans inventories/production/hosts.yml.genere et compare NON destructif : ecrit dans instance/inventories/production/hosts.genere.yml et compare
SEMANTIQUEMENT (via ansible-inventory --list) avec l'inventaire actuel. Aucune SEMANTIQUEMENT (via ansible-inventory --list) avec l'inventaire actuel. Aucune
bascule tant que la comparaison n'est pas vide et validee. bascule tant que la comparaison n'est pas vide et validee.
@ -35,8 +35,8 @@ from inventory_rules import (
RACINE = Path(__file__).resolve().parents[1] RACINE = Path(__file__).resolve().parents[1]
INSTANCE = Path(os.environ.get("SETOPS_INSTANCE") or (RACINE / "instance")) INSTANCE = Path(os.environ.get("SETOPS_INSTANCE") or (RACINE / "instance"))
INVENTAIRE = RACINE / "inventories/production/hosts.yml" INVENTAIRE = INSTANCE / "inventories/production/hosts.yml"
GENERE = RACINE / "inventories/production/hosts.genere.yml" GENERE = INSTANCE / "inventories/production/hosts.genere.yml"
FICHIER_SERVEURS = INSTANCE / "plan/serveurs.yml" FICHIER_SERVEURS = INSTANCE / "plan/serveurs.yml"
FICHIER_APPLICATIONS = INSTANCE / "plan/applications.yml" FICHIER_APPLICATIONS = INSTANCE / "plan/applications.yml"
FICHIER_NOMENCLATURE = INSTANCE / "plan/nomenclature.yml" FICHIER_NOMENCLATURE = INSTANCE / "plan/nomenclature.yml"

View file

@ -38,8 +38,8 @@ from inventory_rules import (
RACINE = Path(__file__).resolve().parents[1] RACINE = Path(__file__).resolve().parents[1]
INSTANCE = Path(os.environ.get("SETOPS_INSTANCE") or (RACINE / "instance")) INSTANCE = Path(os.environ.get("SETOPS_INSTANCE") or (RACINE / "instance"))
INVENTAIRE_DEFAUT = RACINE / "inventories/production/hosts.yml" INVENTAIRE_DEFAUT = INSTANCE / "inventories/production/hosts.yml"
INVENTAIRE_PRODUCTION = (RACINE / "inventories/production/hosts.yml").resolve() INVENTAIRE_PRODUCTION = (INSTANCE / "inventories/production/hosts.yml").resolve()
DOSSIER_PLAYBOOKS_GROUPES = RACINE / "playbooks/groupes" DOSSIER_PLAYBOOKS_GROUPES = RACINE / "playbooks/groupes"
FICHIER_DEPENDANCES = RACINE / "docs/dependances-groupes.yml" FICHIER_DEPENDANCES = RACINE / "docs/dependances-groupes.yml"
FICHIER_NOMENCLATURE = INSTANCE / "plan/nomenclature.yml" FICHIER_NOMENCLATURE = INSTANCE / "plan/nomenclature.yml"

View file

@ -29,7 +29,7 @@ RACINE = Path(__file__).resolve().parents[1]
INSTANCE = Path(os.environ.get("SETOPS_INSTANCE") or (RACINE / "instance")) INSTANCE = Path(os.environ.get("SETOPS_INSTANCE") or (RACINE / "instance"))
FICHIER = INSTANCE / "plan/serveurs.yml" FICHIER = INSTANCE / "plan/serveurs.yml"
FICHIER_NOMENCLATURE = INSTANCE / "plan/nomenclature.yml" FICHIER_NOMENCLATURE = INSTANCE / "plan/nomenclature.yml"
INVENTAIRE = RACINE / "inventories/production/hosts.yml" INVENTAIRE = INSTANCE / "inventories/production/hosts.yml"
# Champs de placement / dimensionnement NON derivables (proviennent du plan). # Champs de placement / dimensionnement NON derivables (proviennent du plan).
CHAMPS_PLAN = [("noeud", "noeud"), ("stockage", "stockage"), CHAMPS_PLAN = [("noeud", "noeud"), ("stockage", "stockage"),