# 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_journal` marche très bien). 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 vs optionnelle.** Compare : retirer `client_journal` d'un nœud → aucun problème (optionnelle). Déclarer une base **sans** serveur → `make instancier`/la validation **échoue** (requise). Tu *sens* la différence de modalité. 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/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.