annuaire : l'hote se derive du plan, il ne s'ecrit plus

`resoudre_annuaire` fixait `id-ldap-01` en dur — une machine qui n'existe dans
aucun plan. Postfix ne pouvait pas se lier : « Can't contact LDAP server ».

L'intention etait juste et son commentaire le disait : un seul point ou le nom
est fixe, au lieu d'etre repete dans chaque role. Mais ECRIT au lieu d'etre
derive. Une valeur unique et fausse vaut mieux qu'une valeur repetee et fausse ;
elle reste fausse.

Le plan le declare (`applications.openldap.hote`) : c'est de la qu'elle vient.

infra-mail-01 et edge-mta-01 deployees, 19 playbooks sans un echec. LMTP en TLS
verifie, mynetworks sur le supernet derive, liaison LDAP etablie vers idm-01.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Daniel Allaire 2026-08-07 12:46:48 -04:00
parent 249fba702a
commit 8260f2f914
3 changed files with 48 additions and 2 deletions

View file

@ -2,6 +2,38 @@
## 2026-08-06 — le chemin nord-sud devient dérivable
### Le courriel interne, et l'annuaire qui ne désignait personne
`infra-mail-01` (Dovecot) et `edge-mta-01` (Postfix + rspamd) déployées — **dix-neuf
playbooks d'affilée sans un échec**. Neuf VM debout.
```
Postfix → Dovecot:24 ouvert
lmtp_tls_security_level = verify zéro-confiance sur le LMTP
mynetworks = … 10.27.0.0/16 le supernet dérivé, à l'œuvre
virtual_mailbox_maps → ldaps://idm-01 liaison établie
```
C'est la seconde branche de la directive d'authentification : LDAP **direct** pour les
protocoles qui ne parlent pas OIDC, sans passer par Keycloak.
**`resoudre_annuaire` fixait `id-ldap-01` en dur** — une machine qui n'existe dans aucun plan.
Postfix ne pouvait pas se lier : `Unable to bind to ldaps://id-ldap-01.chezlepro.internal:636
(Can't contact LDAP server)`.
L'intention du rôle était pourtant juste, et son commentaire le disait : *« LE seul point où le
nom d'hôte de l'annuaire est fixé, au lieu d'être répété dans chaque rôle »*. Un seul point de
vérité — mais **écrit** au lieu d'être dérivé. Une valeur unique et fausse vaut mieux qu'une
valeur répétée et fausse ; elle reste fausse.
Le plan le déclare (`applications.openldap.hote: idm-01`) : c'est de là qu'elle vient
désormais. Septième occurrence du même motif aujourd'hui.
**Ce qui n'est pas prouvé** : aucun compte n'existe dans LDAP — l'approvisionnement des
utilisateurs n'est pas une étape d'infrastructure. Tout ce qui précède la boîte aux lettres est
vérifié ; la remise elle-même attend un compte.
### Le SSO fonctionne — quatre défauts, un seul motif
`obs-01` et `mon-01` déployées : Loki, Prometheus, Grafana d'un côté ; Icinga, Icinga Web 2 et

View file

@ -1,6 +1,10 @@
---
# Hôte qui sert l'annuaire (OpenLDAP). Surchargeable par instance (group_vars) — c'est
# LE seul point où le nom d'hôte de l'annuaire est fixé, au lieu d'être répété dans chaque rôle.
# Hôte qui sert l'annuaire (OpenLDAP) — DÉRIVÉ du plan (`applications.openldap.hote`),
# pas écrit. Un seul point de vérité valait mieux que la répétition dans chaque rôle, mais
# une valeur écrite finit par ne plus désigner personne : `id-ldap-01` ne correspondait à
# aucune machine du plan (l'annuaire vit sur `idm-01`), et Postfix ne pouvait pas se lier.
# Constaté le 2026-08-07. Le repli ci-dessous ne sert que si le plan est muet.
resoudre_annuaire_app: "openldap"
resoudre_annuaire_hote: "id-ldap-01"
resoudre_annuaire_port: 636
resoudre_annuaire_encryption: "ldaps"

View file

@ -17,6 +17,16 @@
- domaine_interne | length > 0
fail_msg: "domaine_interne doit être défini pour résoudre l'annuaire."
- name: Charger le registre des applications (hôte de l'annuaire)
ansible.builtin.include_vars:
file: "{{ setops_plan_dir }}/applications.yml"
failed_when: false
- name: Dériver l'hôte de l'annuaire depuis le plan
ansible.builtin.set_fact:
resoudre_annuaire_hote: "{{ (applications | default({})).get(resoudre_annuaire_app, {}).get('hote') }}"
when: ((applications | default({})).get(resoudre_annuaire_app, {}).get('hote') | default('')) | length > 0
# set_fact (pas les defaults) pour que ces valeurs persistent dans le rôle consommateur
# après include_role (les defaults du rôle inclus ne fuient pas hors de son exécution).
- name: Dériver la connexion à l'annuaire