Solder la dette doc apres le decouplage moteur/instance
Rafraichir les chemins dans docs secondaires, README de roles, messages, docstrings : inventories/ -> instance/inventories/, docs/<plan>.yml -> instance/plan/<plan>.yml. Correction de chemins de playbooks perimes (preexistants) dans CLAUDE.md/SOLUTION.md : vm_templates/..._prepare| verify|cleanup -> modeles_vm/..._preparer|verifier|nettoyer, et confirm_template_cleanup -> template_cleanup_confirm. Valide : diff vide, ansible-lint 0 echec, make inventaire-verifier. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
780b1e6b24
commit
95698a36c0
33 changed files with 68 additions and 67 deletions
|
|
@ -3,6 +3,7 @@
|
|||
## 2026-06-23
|
||||
|
||||
### 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/<plan>.yml` → `instance/plan/<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 `<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.)*
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ Avant de dire qu’un changement est prêt, exécuter au minimum le `--syntax-ch
|
|||
Pour le template Debian 13 Proxmox :
|
||||
|
||||
```bash
|
||||
ansible-playbook -i inventories/lab/hosts.yml playbooks/vm_templates/debian13_proxmox_prepare.yml --syntax-check
|
||||
ansible-playbook -i instance/inventories/lab/hosts.yml playbooks/modeles_vm/debian13_proxmox_preparer.yml --syntax-check
|
||||
```
|
||||
|
||||
Si `ansible-lint` est disponible :
|
||||
|
|
|
|||
|
|
@ -22,25 +22,25 @@ Les rôles sont nommés clairement, sans sous-arborescence complexe.
|
|||
## Commande principale pour construire le template
|
||||
|
||||
```bash
|
||||
ansible-playbook -i inventories/lab/hosts.yml playbooks/vm_templates/debian13_proxmox_prepare.yml --ask-pass --ask-become-pass
|
||||
ansible-playbook -i instance/inventories/lab/hosts.yml playbooks/modeles_vm/debian13_proxmox_preparer.yml --ask-pass --ask-become-pass
|
||||
```
|
||||
|
||||
Après que sudo sans mot de passe fonctionne :
|
||||
|
||||
```bash
|
||||
ansible-playbook -i inventories/lab/hosts.yml playbooks/vm_templates/debian13_proxmox_prepare.yml
|
||||
ansible-playbook -i instance/inventories/lab/hosts.yml playbooks/modeles_vm/debian13_proxmox_preparer.yml
|
||||
```
|
||||
|
||||
## Vérification
|
||||
|
||||
```bash
|
||||
ansible-playbook -i inventories/lab/hosts.yml playbooks/vm_templates/debian13_proxmox_verify.yml
|
||||
ansible-playbook -i instance/inventories/lab/hosts.yml playbooks/modeles_vm/debian13_proxmox_verifier.yml
|
||||
```
|
||||
|
||||
## Nettoyage final avant conversion
|
||||
|
||||
```bash
|
||||
ansible-playbook -i inventories/lab/hosts.yml playbooks/vm_templates/debian13_proxmox_cleanup.yml -e confirm_template_cleanup=true
|
||||
ansible-playbook -i instance/inventories/lab/hosts.yml playbooks/modeles_vm/debian13_proxmox_nettoyer.yml -e template_cleanup_confirm=true
|
||||
```
|
||||
|
||||
Ensuite :
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ La nomenclature des VM et des VMID est documentée dans `docs/nomenclature-vm.md
|
|||
|
||||
Un service central peut partager un hôte avec d'autres services de la même fonction opérationnelle (plusieurs applications par VM). La relation stricte est entre groupe et playbook, pas entre groupe et VM.
|
||||
|
||||
> Modèle à jour : chaque service est une **application** (`docs/applications.yml`). Voir `docs/plan-et-generation.md`.
|
||||
> Modèle à jour : chaque service est une **application** (`instance/plan/applications.yml`). Voir `docs/plan-et-generation.md`.
|
||||
|
||||
## Services centraux
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ chezlepro.internal
|
|||
Elle est definie dans :
|
||||
|
||||
```text
|
||||
inventories/production/group_vars/serveur_powerdns.yml
|
||||
instance/inventories/production/group_vars/serveur_powerdns.yml
|
||||
```
|
||||
|
||||
## Enregistrement automatique
|
||||
|
|
|
|||
|
|
@ -62,11 +62,11 @@ Vérifications utiles depuis le poste Ansible :
|
|||
|
||||
```bash
|
||||
ssh ansible@10.1.99.99
|
||||
ansible -i inventories/lab/hosts.yml modeles_vm -m ping
|
||||
ansible -i inventories/lab/hosts.yml modeles_vm -m setup
|
||||
ansible -i instance/inventories/lab/hosts.yml modeles_vm -m ping
|
||||
ansible -i instance/inventories/lab/hosts.yml modeles_vm -m setup
|
||||
```
|
||||
|
||||
Adapter l'utilisateur et l'adresse IP selon `inventories/lab/hosts.yml`.
|
||||
Adapter l'utilisateur et l'adresse IP selon `instance/inventories/lab/hosts.yml`.
|
||||
|
||||
### Prérequis côté dépôt
|
||||
|
||||
|
|
@ -86,7 +86,7 @@ modeles_vm
|
|||
Les variables du template sont dans :
|
||||
|
||||
```text
|
||||
inventories/lab/group_vars/modeles_vm.yml
|
||||
instance/inventories/lab/group_vars/modeles_vm.yml
|
||||
```
|
||||
|
||||
### Commande de préparation
|
||||
|
|
@ -132,7 +132,7 @@ Un résultat `changed=0` à la relance est le signal que le playbook est idempot
|
|||
|
||||
| Symptôme | Cause probable | Action |
|
||||
| --- | --- | --- |
|
||||
| `UNREACHABLE` | IP, SSH, utilisateur ou clé SSH incorrecte. | Vérifier `inventories/lab/hosts.yml`, cloud-init et tester `ssh`. |
|
||||
| `UNREACHABLE` | IP, SSH, utilisateur ou clé SSH incorrecte. | Vérifier `instance/inventories/lab/hosts.yml`, cloud-init et tester `ssh`. |
|
||||
| échec `become` | Sudo NOPASSWD absent ou utilisateur non autorisé. | Corriger l'accès sudo initial, puis relancer `make preparer-modele`. |
|
||||
| échec APT | DNS, passerelle, miroir Debian ou verrou APT. | Vérifier réseau, DNS et processus APT en cours. |
|
||||
| erreur handler SSH | Handler manquant ou nom `notify` incohérent. | Vérifier les handlers du rôle SSH avant de relancer. |
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ Réseau interne unique : `10.1.0.0/16`. Segmentation par fonction, un `/24` et u
|
|||
|
||||
Adresse d'hôte (4ᵉ octet) : **`service × 10 + NN`**. `.1` = passerelle ; `.2`–`.9` réservés. Exemple : `web-dorsal-01` (catégorie 5, service 4, NN 01) → `10.1.15.41`.
|
||||
|
||||
Tout se dérive de la fonction de l'hôte, et la source unique machine-lisible est **`docs/nomenclature.yml`** :
|
||||
Tout se dérive de la fonction de l'hôte, et la source unique machine-lisible est **`instance/plan/nomenclature.yml`** :
|
||||
|
||||
```text
|
||||
hostname = <fonction>-<NN>
|
||||
|
|
@ -94,13 +94,13 @@ IP = 10.1.<vlan>.(service × 10 + NN)
|
|||
|
||||
`make inventaire-ui` lit ce registre et **propose** automatiquement VMID, VLAN, IP et passerelle quand on nomme un hôte. La sécurité entre zones se fera par règles inter-zones (nftables / edge), pas par l'adressage.
|
||||
|
||||
Contrainte : `NN` de 01 à 09 par fonction (l'octet hôte reste dans le bloc du service). Au-delà, ouvrir une nouvelle fonction/service dans `docs/nomenclature.yml`.
|
||||
Contrainte : `NN` de 01 à 09 par fonction (l'octet hôte reste dans le bloc du service). Au-delà, ouvrir une nouvelle fonction/service dans `instance/plan/nomenclature.yml`.
|
||||
|
||||
La segmentation `10.1.0.0/16` remplace l'ancienne plage d'essais `192.168.12.x`.
|
||||
|
||||
## Variables de provisioning d'hôte
|
||||
|
||||
Le **plan** est la source de vérité du provisioning. Le placement et le dimensionnement d'une VM vivent dans `docs/serveurs.yml` (vue **Serveurs** du GUI) ; VMID / IP / VLAN / passerelle sont **dérivés** de la fonction. Ces variables d'hôte sont alors **générées** dans l'inventaire (ne pas les éditer à la main) :
|
||||
Le **plan** est la source de vérité du provisioning. Le placement et le dimensionnement d'une VM vivent dans `instance/plan/serveurs.yml` (vue **Serveurs** du GUI) ; VMID / IP / VLAN / passerelle sont **dérivés** de la fonction. Ces variables d'hôte sont alors **générées** dans l'inventaire (ne pas les éditer à la main) :
|
||||
|
||||
| Variable | Sens | Type |
|
||||
| --- | --- | --- |
|
||||
|
|
@ -117,16 +117,16 @@ Le **plan** est la source de vérité du provisioning. Le placement et le dimens
|
|||
| `proxmox_memoire` | mémoire en Mo | int |
|
||||
| `proxmox_coeurs` | nombre de cœurs | int |
|
||||
|
||||
Ces valeurs sont **générées** dans l'inventaire depuis `docs/serveurs.yml` + la nomenclature (`make instancier-appliquer`). Une valeur vide n'est pas écrite, pour garder l'inventaire propre.
|
||||
Ces valeurs sont **générées** dans l'inventaire depuis `instance/plan/serveurs.yml` + la nomenclature (`make instancier-appliquer`). Une valeur vide n'est pas écrite, pour garder l'inventaire propre.
|
||||
|
||||
## État d'un hôte (planifié / actif)
|
||||
|
||||
Chaque VM porte un `etat` dans `docs/serveurs.yml` :
|
||||
Chaque VM porte un `etat` dans `instance/plan/serveurs.yml` :
|
||||
|
||||
- `planifie` — prévue mais non encore déployée → groupe `hotes_planifies` à la génération ;
|
||||
- `actif` — réellement joignable par Ansible → groupe `hotes_actifs`.
|
||||
|
||||
L'état se change dans la vue **Serveurs** du GUI (ou `docs/serveurs.yml`), puis on
|
||||
L'état se change dans la vue **Serveurs** du GUI (ou `instance/plan/serveurs.yml`), puis on
|
||||
régénère l'inventaire :
|
||||
|
||||
```bash
|
||||
|
|
@ -135,4 +135,4 @@ make instancier-appliquer
|
|||
|
||||
Les déploiements groupés limitent automatiquement l'exécution à `<groupe demandé> & hotes_actifs`, ce qui permet de décrire l'écosystème complet (hôtes planifiés inclus) sans tenter de configurer une VM qui n'existe pas encore.
|
||||
|
||||
> Les anciennes commandes `make hote-planifier` / `hote-ajouter` éditaient `hosts.yml` directement ; l'inventaire étant désormais **généré**, elles sont supplantées par le plan (`docs/serveurs.yml`).
|
||||
> Les anciennes commandes `make hote-planifier` / `hote-ajouter` éditaient `hosts.yml` directement ; l'inventaire étant désormais **généré**, elles sont supplantées par le plan (`instance/plan/serveurs.yml`).
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ souverain et léger**. Cet assemblage-là est propre à Set-OPS.
|
|||
|
||||
## 2. Ce que Set-OPS fait sciemment maison (et pourquoi)
|
||||
|
||||
- **Le plan déclaratif** (`docs/serveurs.yml`, `applications.yml`, `bases-donnees.yml`,
|
||||
- **Le plan déclaratif** (`instance/plan/serveurs.yml`, `applications.yml`, `bases-donnees.yml`,
|
||||
`domaines.yml`, `nomenclature.yml`) et le **générateur d'inventaire** (`make instancier`).
|
||||
- Le **modèle application-hub** : bindings DSN (portée application/groupe/hôte) et
|
||||
exposition DNS, taillés exactement pour nos concepts.
|
||||
|
|
|
|||
|
|
@ -738,13 +738,13 @@ Après conversion du modèle, le flux normal passe par `make` et l'API Proxmox.
|
|||
Les paramètres communs Proxmox sont dans :
|
||||
|
||||
```text
|
||||
inventories/lab/group_vars/proxmox.yml
|
||||
instance/inventories/lab/group_vars/proxmox.yml
|
||||
```
|
||||
|
||||
Les secrets d'API doivent être dans un fichier Vault non versionné :
|
||||
|
||||
```text
|
||||
inventories/lab/group_vars/proxmox.vault.yml
|
||||
instance/inventories/lab/group_vars/proxmox.vault.yml
|
||||
```
|
||||
|
||||
Créer le clone et l'ajouter à l'inventaire :
|
||||
|
|
|
|||
|
|
@ -169,9 +169,9 @@ Cette commande limite le playbook au croisement entre le groupe demandé et `hot
|
|||
|
||||
## 9. Variables template et conformité
|
||||
|
||||
Les variables du template servent à construire le golden template dans `inventories/lab/group_vars/modeles_vm.yml`.
|
||||
Les variables du template servent à construire le golden template dans `instance/inventories/lab/group_vars/modeles_vm.yml`.
|
||||
|
||||
Les variables de conformité servent aux VM déployées dans `inventories/production/group_vars/serveur_debian.yml`.
|
||||
Les variables de conformité servent aux VM déployées dans `instance/inventories/production/group_vars/serveur_debian.yml`.
|
||||
|
||||
Différence attendue :
|
||||
|
||||
|
|
|
|||
|
|
@ -12,5 +12,5 @@
|
|||
domaine_interne: "acme.internal"
|
||||
|
||||
# Le reste de l'identite vit dans le PLAN de l'instance :
|
||||
# - docs/nomenclature.yml : supernet (ex. 10.1.0.0/16) + liste de fonctions
|
||||
# - docs/serveurs.yml / applications.yml / domaines.yml : le plan rempli
|
||||
# - instance/plan/nomenclature.yml : supernet (ex. 10.1.0.0/16) + liste de fonctions
|
||||
# - instance/plan/serveurs.yml / applications.yml / domaines.yml : le plan rempli
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
tasks:
|
||||
# Couche application : une VM dorsale peut porter PLUSIEURS applications.
|
||||
# On itere donc sur les applications mappees a cet hote (docs/applications.yml),
|
||||
# On itere donc sur les applications mappees a cet hote (instance/plan/applications.yml),
|
||||
# chacune resolvant ses bases via son DSN (regle partagee, filter plugin).
|
||||
- name: Charger les registres applications et bases
|
||||
ansible.builtin.include_vars:
|
||||
|
|
@ -39,5 +39,5 @@
|
|||
|
||||
- name: Avertir si l'hote ne porte aucune application
|
||||
ansible.builtin.debug:
|
||||
msg: "Aucune application declaree sur cet hote (docs/applications.yml). Couche dorsale : API, traitement."
|
||||
msg: "Aucune application declaree sur cet hote (instance/plan/applications.yml). Couche dorsale : API, traitement."
|
||||
when: applications_hote | length == 0
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
tasks:
|
||||
# Couche presentation : une VM frontale peut porter PLUSIEURS applications.
|
||||
# On itere sur les applications mappees a cet hote (docs/applications.yml),
|
||||
# On itere sur les applications mappees a cet hote (instance/plan/applications.yml),
|
||||
# chacune resolvant ses bases via son DSN (regle partagee, filter plugin).
|
||||
- name: Charger les registres applications et bases
|
||||
ansible.builtin.include_vars:
|
||||
|
|
@ -39,5 +39,5 @@
|
|||
|
||||
- name: Avertir si l'hote ne porte aucune application
|
||||
ansible.builtin.debug:
|
||||
msg: "Aucune application declaree sur cet hote (docs/applications.yml). Couche presentation, derriere serveur_nginx."
|
||||
msg: "Aucune application declaree sur cet hote (instance/plan/applications.yml). Couche presentation, derriere serveur_nginx."
|
||||
when: applications_hote | length == 0
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ python3 -c 'import proxmoxer'
|
|||
Les paramètres non sensibles sont dans :
|
||||
|
||||
```text
|
||||
inventories/lab/group_vars/proxmox.yml
|
||||
instance/inventories/lab/group_vars/proxmox.yml
|
||||
```
|
||||
|
||||
Assistant terminal :
|
||||
|
|
@ -40,14 +40,14 @@ make config
|
|||
Les secrets d'API doivent être dans un fichier Vault non versionné :
|
||||
|
||||
```text
|
||||
inventories/lab/group_vars/proxmox.vault.yml
|
||||
instance/inventories/lab/group_vars/proxmox.vault.yml
|
||||
```
|
||||
|
||||
Créer le fichier depuis l'exemple, puis le chiffrer :
|
||||
|
||||
```bash
|
||||
cp inventories/lab/group_vars/proxmox.vault.yml.example inventories/lab/group_vars/proxmox.vault.yml
|
||||
ansible-vault encrypt inventories/lab/group_vars/proxmox.vault.yml
|
||||
cp instance/inventories/lab/group_vars/proxmox.vault.yml.example instance/inventories/lab/group_vars/proxmox.vault.yml
|
||||
ansible-vault encrypt instance/inventories/lab/group_vars/proxmox.vault.yml
|
||||
```
|
||||
|
||||
Créer un clone Debian depuis le modèle :
|
||||
|
|
|
|||
|
|
@ -10,9 +10,9 @@
|
|||
ansible.builtin.stat:
|
||||
path: "{{ item }}"
|
||||
loop:
|
||||
- "{{ playbook_dir }}/../../inventories/lab/group_vars/proxmox.yml"
|
||||
- "{{ playbook_dir }}/../../inventories/lab/group_vars/proxmox.vault.yml"
|
||||
- "{{ playbook_dir }}/../../inventories/lab/group_vars/proxmox.local.yml"
|
||||
- "{{ playbook_dir }}/../../instance/inventories/lab/group_vars/proxmox.yml"
|
||||
- "{{ playbook_dir }}/../../instance/inventories/lab/group_vars/proxmox.vault.yml"
|
||||
- "{{ playbook_dir }}/../../instance/inventories/lab/group_vars/proxmox.local.yml"
|
||||
register: proxmox_fichiers_variables
|
||||
|
||||
- name: Charger les variables Proxmox non sensibles disponibles
|
||||
|
|
@ -37,7 +37,7 @@
|
|||
- name: Expliquer l echec de chargement du Vault
|
||||
ansible.builtin.fail:
|
||||
msg: >-
|
||||
Impossible de charger inventories/lab/group_vars/proxmox.vault.yml.
|
||||
Impossible de charger instance/inventories/lab/group_vars/proxmox.vault.yml.
|
||||
Si le fichier est chiffre avec Ansible Vault, fournir son mot de passe
|
||||
ou definir ANSIBLE_VAULT_PASSWORD_FILE avant de relancer make creer-vm.
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ Forge Git **Forgejo** (binaire officiel) — dépôts Git, CI, revue de code.
|
|||
## Rôle
|
||||
- Installe le binaire Forgejo (version épinglée, lien symbolique courant), utilisateur `git`.
|
||||
- Crée l'arborescence (`/var/lib/forgejo`, `/etc/forgejo`).
|
||||
- **Base PostgreSQL via le registre** (`docs/bases-donnees.yml`, entrée `forgejo`).
|
||||
- **Base PostgreSQL via le registre** (`instance/plan/bases-donnees.yml`, entrée `forgejo`).
|
||||
- `app.ini` : serveur derrière nginx (`HTTP_ADDR=127.0.0.1`, `ROOT_URL` https), DB, secrets, mailer vers `serveur_sendmail`, inscription désactivée, `INSTALL_LOCK` (pas d'assistant web).
|
||||
- Service systemd + création du **compte administrateur** initial (une fois).
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@
|
|||
that:
|
||||
- serveur_forgejo_entree.base is defined
|
||||
- serveur_forgejo_entree.secret is defined
|
||||
fail_msg: "Aucune base avec consommateur '{{ serveur_forgejo_groupe }}' dans docs/bases-donnees.yml."
|
||||
fail_msg: "Aucune base avec consommateur '{{ serveur_forgejo_groupe }}' dans instance/plan/bases-donnees.yml."
|
||||
|
||||
- name: Resoudre le mot de passe de base (Vault)
|
||||
ansible.builtin.set_fact:
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ Icinga DB** (avec son Redis dédié et sa base PostgreSQL). **Icinga Web 2 est d
|
|||
- Ajoute le **dépôt apt officiel Icinga** (trousseau + source signée) et installe
|
||||
`icinga2`, `icingadb`, `icingadb-redis`.
|
||||
- `icinga2 api setup` + activation de la fonctionnalité `icingadb`.
|
||||
- **Base PostgreSQL via le registre** (`docs/bases-donnees.yml`, entrée `icingadb`) :
|
||||
- **Base PostgreSQL via le registre** (`instance/plan/bases-donnees.yml`, entrée `icingadb`) :
|
||||
PostgreSQL crée la base/compte, ce rôle importe le **schéma** et écrit
|
||||
`/etc/icingadb/config.yml` (BD + Redis).
|
||||
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@
|
|||
that:
|
||||
- serveur_icinga_entree.base is defined
|
||||
- serveur_icinga_entree.secret is defined
|
||||
fail_msg: "Aucune base avec consommateur '{{ serveur_icinga_groupe }}' dans docs/bases-donnees.yml."
|
||||
fail_msg: "Aucune base avec consommateur '{{ serveur_icinga_groupe }}' dans instance/plan/bases-donnees.yml."
|
||||
|
||||
- name: Resoudre le mot de passe de base (Vault)
|
||||
ansible.builtin.set_fact:
|
||||
|
|
|
|||
|
|
@ -5,13 +5,13 @@ SSO / IAM **Keycloak** (distribution Quarkus) — hub d'authentification central
|
|||
|
||||
## Rôle
|
||||
- Installe un JRE, télécharge et extrait la distribution Keycloak dans `/opt/keycloak`.
|
||||
- Configure la **base PostgreSQL via le registre** `docs/bases-donnees.yml` (entrée `keycloak`).
|
||||
- Configure la **base PostgreSQL via le registre** `instance/plan/bases-donnees.yml` (entrée `keycloak`).
|
||||
- Publie derrière `serveur_nginx` (TLS à l'edge) : `hostname`, `proxy-headers=xforwarded`, `http-enabled=true`.
|
||||
- Secrets (mot de passe BD + admin bootstrap) dans `/etc/keycloak/keycloak.env` (`0640`, `no_log`).
|
||||
- `kc.sh build --db=postgres` (une fois par version) puis service systemd `start --optimized`.
|
||||
|
||||
## Premier consommateur du registre de BD
|
||||
L'entrée `keycloak` de `docs/bases-donnees.yml` fait que :
|
||||
L'entrée `keycloak` de `instance/plan/bases-donnees.yml` fait que :
|
||||
1. `serveur_postgresql` crée la base `keycloak` + le compte propriétaire `keycloak`.
|
||||
2. Ce rôle lit **la même entrée** pour bâtir sa connexion (`db-url-database`, `db-username`, mot de passe = `vault_bd_keycloak`).
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
- serveur_keycloak_entree.base is defined
|
||||
- serveur_keycloak_entree.proprietaire is defined
|
||||
- serveur_keycloak_entree.secret is defined
|
||||
fail_msg: "Aucune base avec consommateur '{{ serveur_keycloak_groupe }}' dans docs/bases-donnees.yml."
|
||||
fail_msg: "Aucune base avec consommateur '{{ serveur_keycloak_groupe }}' dans instance/plan/bases-donnees.yml."
|
||||
|
||||
- name: Resoudre le mot de passe de base de donnees (Vault)
|
||||
ansible.builtin.set_fact:
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ serveur_nginx_redirection_http: true # 80 -> 443
|
|||
serveur_nginx_desactiver_defaut: false # retirer le site Debian par defaut
|
||||
|
||||
# Sites de reverse proxy declares a la main. Vide par defaut.
|
||||
# S'AJOUTENT aux vhosts derives automatiquement de docs/domaines.yml.
|
||||
# S'AJOUTENT aux vhosts derives automatiquement de instance/plan/domaines.yml.
|
||||
serveur_nginx_sites: []
|
||||
# - nom: forge
|
||||
# domaine: forge.{{ domaine_interne }}
|
||||
|
|
@ -29,10 +29,10 @@ serveur_nginx_sites: []
|
|||
# cle: "/etc/ssl/.../forge.key"
|
||||
|
||||
# Groupe edge auquel ce role s'identifie (pour filtrer le champ "edge" de
|
||||
# docs/domaines.yml). Permet plusieurs edges distincts a terme.
|
||||
# instance/plan/domaines.yml). Permet plusieurs edges distincts a terme.
|
||||
serveur_nginx_groupe: "serveur_nginx"
|
||||
|
||||
# Deriver automatiquement des vhosts depuis docs/domaines.yml (bloc "exposition").
|
||||
# Deriver automatiquement des vhosts depuis instance/plan/domaines.yml (bloc "exposition").
|
||||
# Pour chaque exposition de type "web" dont l'edge vise ce groupe, un vhost est
|
||||
# genere : amont = entree "amont" explicite, sinon http://<IP interne de la
|
||||
# cible>:<port>. Une exposition non resolvable (cible sans hote actif, ou sans
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Vhosts derives des applications (champ 'expose' de docs/applications.yml,
|
||||
# edge depuis docs/domaines.yml) — gere par Set-OPS (role serveur_nginx).
|
||||
# Vhosts derives des applications (champ 'expose' de instance/plan/applications.yml,
|
||||
# edge depuis instance/plan/domaines.yml) — gere par Set-OPS (role serveur_nginx).
|
||||
# Ne pas editer a la main.
|
||||
#
|
||||
# Un FQDN expose produit un vhost si l'hote de l'application est resolvable :
|
||||
|
|
|
|||
|
|
@ -41,12 +41,12 @@ serveur_postgresql_bases:
|
|||
```
|
||||
|
||||
## Registre partagé des bases applicatives
|
||||
En plus des listes explicites, le rôle lit **`docs/bases-donnees.yml`** (registre
|
||||
En plus des listes explicites, le rôle lit **`instance/plan/bases-donnees.yml`** (registre
|
||||
déclaratif) et crée chaque base + son compte propriétaire dont `serveur` vaut
|
||||
`serveur_postgresql`. Le mot de passe vient de la variable Vault nommée par le
|
||||
champ `secret`. Le rôle applicatif lit le même registre pour bâtir sa chaîne de
|
||||
connexion — secret partagé, source unique. Patron : 1 appli → 1 base → 1 owner →
|
||||
1 chaîne de connexion. Voir l'en-tête de `docs/bases-donnees.yml`.
|
||||
1 chaîne de connexion. Voir l'en-tête de `instance/plan/bases-donnees.yml`.
|
||||
|
||||
## Prérequis
|
||||
- Collection `community.postgresql` (`ansible-galaxy collection install community.postgresql`).
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ serveur_postgresql_methode_auth: "scram-sha-256"
|
|||
serveur_postgresql_parametres: {}
|
||||
|
||||
# Nom du groupe serveur (pour filtrer le registre des bases applicatives).
|
||||
# Le registre lui-meme (bases_donnees) est charge depuis docs/bases-donnees.yml.
|
||||
# Le registre lui-meme (bases_donnees) est charge depuis instance/plan/bases-donnees.yml.
|
||||
serveur_postgresql_groupe: "serveur_postgresql"
|
||||
|
||||
# Provisioning applicatif explicite. Vide par defaut : aucune base ni compte cree.
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@
|
|||
label: "{{ item.nom }}"
|
||||
when: serveur_postgresql_bases | length > 0
|
||||
|
||||
# --- Provisioning depuis le registre partage docs/bases-donnees.yml ---
|
||||
# --- Provisioning depuis le registre partage instance/plan/bases-donnees.yml ---
|
||||
|
||||
- name: Charger le registre des bases applicatives
|
||||
ansible.builtin.include_vars:
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ serveur_step_ca_password: "{{ vault_step_ca_password }}"
|
|||
serveur_step_ca_provisioner_password: "{{ vault_step_ca_provisioner_password }}"
|
||||
```
|
||||
|
||||
À placer dans `inventories/production/group_vars/serveur_step_ca/vault.yml` (chiffré),
|
||||
À placer dans `instance/inventories/production/group_vars/serveur_step_ca/vault.yml` (chiffré),
|
||||
les variables en clair référençant ces secrets dans `.../serveur_step_ca/main.yml`.
|
||||
|
||||
## Variables principales
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
#!/usr/bin/env python3
|
||||
"""Lit et valide le registre des applications Set-OPS (docs/applications.yml)."""
|
||||
"""Lit et valide le registre des applications Set-OPS (instance/plan/applications.yml)."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
|
|
@ -130,7 +130,7 @@ def main() -> int:
|
|||
registre = bootstrap(registre)
|
||||
valider_applications(registre, domaines)
|
||||
ecrire(registre)
|
||||
print(f"docs/applications.yml genere depuis l'inventaire ({len(registre['applications'])} applications).")
|
||||
print(f"instance/plan/applications.yml genere depuis l'inventaire ({len(registre['applications'])} applications).")
|
||||
elif args.commande == "ajouter":
|
||||
app = {"groupe": args.groupe, "hote": args.hote}
|
||||
if args.port is not None:
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
#!/usr/bin/env python3
|
||||
"""Lit et valide le registre des domaines publics Set-OPS (docs/domaines.yml)."""
|
||||
"""Lit et valide le registre des domaines publics Set-OPS (instance/plan/domaines.yml)."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ bascule tant que la comparaison n'est pas vide et validee.
|
|||
|
||||
Derivation :
|
||||
- host vars : ansible_host/ansible_user + proxmox_* (IP/VMID/VLAN/passerelle
|
||||
derives de la nomenclature ; placement/taille depuis docs/serveurs.yml) ;
|
||||
derives de la nomenclature ; placement/taille depuis instance/plan/serveurs.yml) ;
|
||||
- groupes : socle (serveur_debian/durcis) + groupes de service derives des
|
||||
applications de l'hote + groupe d'etat (hotes_actifs/hotes_planifies).
|
||||
- Les integrations clients_* ne sont PAS derivables du plan a ce stade : la
|
||||
|
|
@ -85,8 +85,8 @@ def generer() -> dict:
|
|||
|
||||
def ecrire(path: Path = GENERE) -> None:
|
||||
entete = ("# Inventaire GENERE depuis le plan (make instancier / instancier-appliquer).\n"
|
||||
"# NE PAS editer a la main : edite docs/serveurs.yml + docs/applications.yml.\n"
|
||||
"# Source : docs/serveurs.yml + docs/applications.yml + docs/nomenclature.yml.\n")
|
||||
"# NE PAS editer a la main : edite instance/plan/serveurs.yml + instance/plan/applications.yml.\n"
|
||||
"# Source : instance/plan/serveurs.yml + instance/plan/applications.yml + instance/plan/nomenclature.yml.\n")
|
||||
with path.open("w", encoding="utf-8") as fichier:
|
||||
fichier.write(entete)
|
||||
yaml.safe_dump(generer(), fichier, default_flow_style=False, sort_keys=True, allow_unicode=True)
|
||||
|
|
|
|||
|
|
@ -247,7 +247,7 @@ def ecrire_serveurs(path: Path, registre: dict) -> None:
|
|||
entete = (
|
||||
"# Registre des serveurs (VM) du plan Set-OPS.\n"
|
||||
"# Edite par make inventaire-ui ou scripts/serveurs.py.\n"
|
||||
"# VMID/IP/VLAN/passerelle sont DERIVES de la fonction via docs/nomenclature.yml.\n"
|
||||
"# VMID/IP/VLAN/passerelle sont DERIVES de la fonction via instance/plan/nomenclature.yml.\n"
|
||||
"---\n"
|
||||
)
|
||||
with path.open("w", encoding="utf-8") as fichier:
|
||||
|
|
@ -1570,7 +1570,7 @@ class Gestionnaire(BaseHTTPRequestHandler):
|
|||
try:
|
||||
if chemin == "/api/inventaire":
|
||||
self.repondre_json(409, {"erreur": "hosts.yml est genere depuis le plan. "
|
||||
"Edite docs/serveurs.yml et docs/applications.yml "
|
||||
"Edite instance/plan/serveurs.yml et instance/plan/applications.yml "
|
||||
"(vues Serveurs / Applications), puis « Appliquer le plan »."})
|
||||
elif chemin == "/api/bases":
|
||||
valider_bases(donnees, charger_applications(FICHIER_APPLICATIONS))
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ def valider_bases(registre: dict, applications: dict | None = None) -> None:
|
|||
if portee == "groupe" and not est_groupe_operationnel(base["consommateur"]):
|
||||
raise ValueError(f"Base '{cle}': portee groupe mais consommateur '{base['consommateur']}' non operationnel.")
|
||||
if portee == "application" and apps and base["consommateur"] not in apps:
|
||||
raise ValueError(f"Base '{cle}': application consommatrice '{base['consommateur']}' inconnue (docs/applications.yml).")
|
||||
raise ValueError(f"Base '{cle}': application consommatrice '{base['consommateur']}' inconnue (instance/plan/applications.yml).")
|
||||
couple = f"{base['serveur']}/{base['base']}"
|
||||
if couple in noms_bases:
|
||||
raise ValueError(f"Base en double sur un meme serveur: {couple}")
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ def ecrire(registre: dict) -> None:
|
|||
"# Registre des serveurs (VM) du plan Set-OPS.\n"
|
||||
"# Bootstrape depuis l'inventaire (make serveurs-bootstrap). L'inventaire\n"
|
||||
"# reste autorite en Phase 2 ; VMID/IP/VLAN/passerelle sont DERIVES de la\n"
|
||||
"# fonction via docs/nomenclature.yml (non stockes ici).\n"
|
||||
"# fonction via instance/plan/nomenclature.yml (non stockes ici).\n"
|
||||
"---\n"
|
||||
)
|
||||
with FICHIER.open("w", encoding="utf-8") as fichier:
|
||||
|
|
@ -115,7 +115,7 @@ def main() -> int:
|
|||
sub = parser.add_subparsers(dest="commande", required=True)
|
||||
sub.add_parser("lister", help="Affiche les serveurs et leur reconciliation avec l'inventaire.")
|
||||
sub.add_parser("verifier", help="Valide le registre et signale les divergences.")
|
||||
sub.add_parser("bootstrap", help="(Re)genere docs/serveurs.yml depuis l'inventaire actuel.")
|
||||
sub.add_parser("bootstrap", help="(Re)genere instance/plan/serveurs.yml depuis l'inventaire actuel.")
|
||||
|
||||
args = parser.parse_args()
|
||||
try:
|
||||
|
|
@ -127,7 +127,7 @@ def main() -> int:
|
|||
registre = bootstrap()
|
||||
valider_serveurs(registre, charger_nomenclature(FICHIER_NOMENCLATURE))
|
||||
ecrire(registre)
|
||||
print(f"docs/serveurs.yml genere depuis l'inventaire ({len(registre['serveurs'])} serveurs).")
|
||||
print(f"instance/plan/serveurs.yml genere depuis l'inventaire ({len(registre['serveurs'])} serveurs).")
|
||||
except Exception as exc:
|
||||
print(f"erreur: {exc}", file=sys.stderr)
|
||||
return 2
|
||||
|
|
|
|||
Reference in a new issue