Set-OPS-Public/wiki/Liaisons-bindings.md
Daniel Allaire aab1bcc83a doc : rangee par lecteur, trois portes d'entree (architecture, setup, usage) et un index
README reduit au role du projet et au demarrage rapide. docs/architecture.md (schemas
Mermaid), docs/setup.md, docs/usage.md (154 cibles en 13 familles), docs/README.md (index).
Documents ranges en conception/, exploitation/, hebergement/, projet/ ; 598 chemins suivis.
QUICKSTART.md, SOLUTION.md, architecture-set-ops.md et la carte fondus puis retires.

Preuves : P48 lit l'index et conception/mecanismes.md ; les gardes parcourent docs/ sous-
dossiers compris (_documents) ; usage.md suit le Makefile dans les deux sens.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 01:01:54 -04:00

89 lines
4.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Liaisons (bindings)
> **Unité d'apprentissage.** Moule : ① concept → ② Set-OPS → ③ transférable → ④ à toi de jouer.
---
## ① Le concept *(générique)*
Un système réel n'est pas fait de pièces isolées, mais de **relations** : cette app *utilise* cette
base, ce serveur *fait confiance* à cette AC, ce nœud *envoie ses logs* à ce collecteur.
Deux façons de câbler ces relations :
- **En dur** — recopier l'adresse/le nom dans chaque config. Fragile : déplacer une pièce oblige à
éditer partout, et ça casse la portabilité.
- **En liaisons déclaratives** — on **déclare** « A est lié à B », et le **moteur résout** l'adresse
concrète au bon moment. Déplacer B ? On ne touche qu'un endroit.
> **Analogie NetScaler (Citrix ADC)** : tu *bind* un *service* à un *vserver*, une *policy* à un
> *vserver*, un *monitor* à un *service*. Tu ne codes pas des IP en dur — tu **relies des entités**,
> et l'appareil fait le reste. Les liaisons de Set-OPS, c'est exactement ce modèle.
Deux **axes** pour classer une liaison (indépendants) :
- **Niveau** : *app→app/base/domaine* (`liens`) ou *nœud→service de flotte* (`intégrations`).
- **Modalité** : **requise** (constitutive — sans elle, ça ne s'instancie pas) ou **optionnelle**
(élective — un choix, l'absence est légitime).
---
## ② Comment Set-OPS le fait
| Type | Où | Résolu en | Exemple |
|---|---|---|---|
| **`liens`** | `applications.yml` | **config** (host_vars, lookups) | Forgejo → sa base ; app → domaine exposé |
| **`intégrations`** | `serveurs.yml` | **groupe + agent client** | nœud → PKI, sauvegarde, métriques… |
Les **résolveurs partagés** font le pont : `resoudre_base` (app→base) et `resoudre_annuaire`
(app→annuaire) lisent un **registre** et bâtissent la connexion — le secret restant déréférencé
**dans le rôle**, jamais en clair.
La **modalité** structure la robustesse : une liaison **requise** absente → le moteur **refuse
d'instancier** (ex. une base sans serveur SQL). Une **optionnelle** absente → silence (ex. un
nœud sans `client_backup` : il ne détient pas d'état, il n'a rien à sauvegarder).
> **Attention à une troisième catégorie, qui n'est ni l'une ni l'autre : l'universelle.**
> `client_pki`, `client_metrique`, `client_journal`, `client_resolveur` et
> `client_artefacts` ne se déclarent **pas** — tout hôte les reçoit par dérivation, et
> **P26** refuse qu'un hôte y échappe. Cette unité citait `client_journal` en exemple
> d'optionnelle jusqu'au 2026-09-06 : c'est l'inverse. Le plan portait 28 lignes qui
> disaient « oui » à quelque chose de vrai pour tous ; elles n'existaient que pour être
> oubliées, et quatre l'avaient été.
C'est **le** concept de Set-OPS : *tu déclares les liaisons, le moteur câble.*
---
## ③ Pourquoi c'est transférable
| Set-OPS | Équivalents ailleurs |
|---|---|
| liens/intégrations déclaratifs | **NetScaler bindings** · références de ressources Terraform |
| service ↔ backend | Kubernetes : Service↔Pods, Ingress↔Service |
| requis vs optionnel | dépendances *hard* vs *soft* (partout) |
Tu as appris **la relation déclarative, la résolution par un moteur, requis vs optionnel** — pas un
produit. C'est un **modèle mental** qui vaut de NetScaler à Kubernetes.
---
## ④ À toi de jouer
1. **Lis une liaison.** Ouvre `instance/plan/applications.yml` : une app avec `expose:` (liaison
*app→domaine*), et `serveurs.yml` : un nœud avec `integrations:` (liaison *nœud→service*).
2. **Vois-la se résoudre.** Après `make instancier`, regarde l'inventaire généré : la cible est
devenue une **valeur concrète** (FQDN, groupe) — le moteur a câblé.
3. **Requise, optionnelle, universelle.** Compare les trois : retirer `client_backup` d'un
nœud sans état → aucun problème (**optionnelle**). Déclarer une base **sans** serveur →
`make instancier` **échoue** (**requise**). Essayer de recopier `client_metrique` dans
`serveurs.yml` → le plan **refuse** (**universelle** : elle est dérivée, la recopier
créerait une seconde source qui finirait par diverger).
4. **Casse & répare.** Casse une liaison requise (ex. réfère une base à un serveur inexistant),
relance l'instanciation : **échec clair** *avant* tout déploiement. Corrige : ça passe. Le moteur
attrape le câblage manquant à ta place.
---
## Pour aller plus loin *(dépôt)*
- Conception + **taxonomie (niveau × modalité)** : `docs/conception/bindings-conception.md` (§11).
- Résolveurs : `roles/resoudre_base`, `roles/resoudre_annuaire` ; registres : `instance/plan/`.
- Toutes les autres unités sont, au fond, des liaisons en action.