serveur_ops : la difference entre une archive et une matrice
Un ecosysteme pouvait DETENIR son genome sans savoir l'executer. Le poste
d'exploitation porte Ansible epingle, le genome clone depuis SA PROPRE forge, et
une cle SSH qui n'appartient qu'a lui. Il n'emporte ni la voute ni son mot de
passe : la structure se reconstruit depuis la forge, les secrets depuis la
sauvegarde. Deux sources qu'un meme incident n'atteint pas ensemble.
Une machine neuve traverse tout le moteur sans rien heriter, et revele ce qu'un
etat anterieur masquait. Deux defauts silencieux en sont sortis.
setops_plan_dir pointait le lien `instance` en dur : neuf roles lisaient donc le
plan d'une AUTRE instance. Le plancher de patient 0 portait les FQDN de
Chezlepro, et son edge publiait server_name forge.chezlepro.internal. La
variable suit desormais l'inventaire reellement charge.
Trois instances sur quatre declaraient les SAN d'exposition de leur edge ; la
quatrieme et le modele public ne les avaient pas. La forge de patient 0 etait
donc publiee derriere le certificat auto-signe de Debian, sans que rien ne le
signale -- `git clone` fut le premier a refuser, a juste titre. P42 le reclame
maintenant pour tout ecosysteme qui declare un edge.
Le harnais a ecrit la moitie de ce role : 5 echecs sur la piece neuve, aucun
n'empechait le code de tourner, tous la rendaient invisible a la carte, au
graphe et au lecteur. 42 preuves, 0 echec.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-23 11:58:10 -04:00
|
|
|
---
|
2026-08-24 11:42:32 -04:00
|
|
|
# UN POSTE QUI NE SAIT PAS QUEL ÉCOSYSTÈME IL PILOTE N'A RIEN À PILOTER.
|
|
|
|
|
#
|
|
|
|
|
# On exige explicitement un dépôt d'instance, plutôt que de retomber sur un défaut : le
|
|
|
|
|
# défaut nommait patient 0, et un écosystème distrait aurait cloné le génome d'un autre
|
|
|
|
|
# sans qu'aucune erreur ne le signale.
|
serveur_ops : la difference entre une archive et une matrice
Un ecosysteme pouvait DETENIR son genome sans savoir l'executer. Le poste
d'exploitation porte Ansible epingle, le genome clone depuis SA PROPRE forge, et
une cle SSH qui n'appartient qu'a lui. Il n'emporte ni la voute ni son mot de
passe : la structure se reconstruit depuis la forge, les secrets depuis la
sauvegarde. Deux sources qu'un meme incident n'atteint pas ensemble.
Une machine neuve traverse tout le moteur sans rien heriter, et revele ce qu'un
etat anterieur masquait. Deux defauts silencieux en sont sortis.
setops_plan_dir pointait le lien `instance` en dur : neuf roles lisaient donc le
plan d'une AUTRE instance. Le plancher de patient 0 portait les FQDN de
Chezlepro, et son edge publiait server_name forge.chezlepro.internal. La
variable suit desormais l'inventaire reellement charge.
Trois instances sur quatre declaraient les SAN d'exposition de leur edge ; la
quatrieme et le modele public ne les avaient pas. La forge de patient 0 etait
donc publiee derriere le certificat auto-signe de Debian, sans que rien ne le
signale -- `git clone` fut le premier a refuser, a juste titre. P42 le reclame
maintenant pour tout ecosysteme qui declare un edge.
Le harnais a ecrit la moitie de ce role : 5 echecs sur la piece neuve, aucun
n'empechait le code de tourner, tous la rendaient invisible a la carte, au
graphe et au lecteur. 42 preuves, 0 echec.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-23 11:58:10 -04:00
|
|
|
- name: Exiger les intrants du poste d'exploitation
|
|
|
|
|
ansible.builtin.assert:
|
|
|
|
|
that:
|
|
|
|
|
- domaine_interne | default('') | length > 0
|
2026-08-24 11:42:32 -04:00
|
|
|
- (serveur_ops_depots | selectattr('role', 'eq', 'moteur') | list | length) == 1
|
|
|
|
|
- (serveur_ops_depots | selectattr('role', 'eq', 'instance') | list | length) >= 1
|
|
|
|
|
- serveur_ops_instance | default('') | length > 0
|
2026-08-24 14:10:10 -04:00
|
|
|
- not (serveur_ops_forge_externe | bool) or (serveur_ops_forge_amont | length > 0)
|
serveur_ops : la difference entre une archive et une matrice
Un ecosysteme pouvait DETENIR son genome sans savoir l'executer. Le poste
d'exploitation porte Ansible epingle, le genome clone depuis SA PROPRE forge, et
une cle SSH qui n'appartient qu'a lui. Il n'emporte ni la voute ni son mot de
passe : la structure se reconstruit depuis la forge, les secrets depuis la
sauvegarde. Deux sources qu'un meme incident n'atteint pas ensemble.
Une machine neuve traverse tout le moteur sans rien heriter, et revele ce qu'un
etat anterieur masquait. Deux defauts silencieux en sont sortis.
setops_plan_dir pointait le lien `instance` en dur : neuf roles lisaient donc le
plan d'une AUTRE instance. Le plancher de patient 0 portait les FQDN de
Chezlepro, et son edge publiait server_name forge.chezlepro.internal. La
variable suit desormais l'inventaire reellement charge.
Trois instances sur quatre declaraient les SAN d'exposition de leur edge ; la
quatrieme et le modele public ne les avaient pas. La forge de patient 0 etait
donc publiee derriere le certificat auto-signe de Debian, sans que rien ne le
signale -- `git clone` fut le premier a refuser, a juste titre. P42 le reclame
maintenant pour tout ecosysteme qui declare un edge.
Le harnais a ecrit la moitie de ce role : 5 echecs sur la piece neuve, aucun
n'empechait le code de tourner, tous la rendaient invisible a la carte, au
graphe et au lecteur. 42 preuves, 0 echec.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-23 11:58:10 -04:00
|
|
|
fail_msg: >-
|
2026-08-24 11:42:32 -04:00
|
|
|
serveur_ops exige `domaine_interne`, exactement un dépôt `role: moteur`, au moins
|
|
|
|
|
un dépôt `role: instance`, et `serveur_ops_instance` (le dossier que le lien
|
2026-08-24 14:10:10 -04:00
|
|
|
`instance` doit désigner). Et si `serveur_ops_forge_externe` est levé — écosystème
|
|
|
|
|
au premier âge, qui lit son génome chez son hôte — `serveur_ops_forge_amont` doit
|
|
|
|
|
nommer cette forge. Déclarer le tout dans group_vars/serveur_ops.yml.
|
serveur_ops : la difference entre une archive et une matrice
Un ecosysteme pouvait DETENIR son genome sans savoir l'executer. Le poste
d'exploitation porte Ansible epingle, le genome clone depuis SA PROPRE forge, et
une cle SSH qui n'appartient qu'a lui. Il n'emporte ni la voute ni son mot de
passe : la structure se reconstruit depuis la forge, les secrets depuis la
sauvegarde. Deux sources qu'un meme incident n'atteint pas ensemble.
Une machine neuve traverse tout le moteur sans rien heriter, et revele ce qu'un
etat anterieur masquait. Deux defauts silencieux en sont sortis.
setops_plan_dir pointait le lien `instance` en dur : neuf roles lisaient donc le
plan d'une AUTRE instance. Le plancher de patient 0 portait les FQDN de
Chezlepro, et son edge publiait server_name forge.chezlepro.internal. La
variable suit desormais l'inventaire reellement charge.
Trois instances sur quatre declaraient les SAN d'exposition de leur edge ; la
quatrieme et le modele public ne les avaient pas. La forge de patient 0 etait
donc publiee derriere le certificat auto-signe de Debian, sans que rien ne le
signale -- `git clone` fut le premier a refuser, a juste titre. P42 le reclame
maintenant pour tout ecosysteme qui declare un edge.
Le harnais a ecrit la moitie de ce role : 5 echecs sur la piece neuve, aucun
n'empechait le code de tourner, tous la rendaient invisible a la carte, au
graphe et au lecteur. 42 preuves, 0 echec.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-23 11:58:10 -04:00
|
|
|
|
|
|
|
|
- name: Installer l'outillage du poste
|
|
|
|
|
ansible.builtin.apt:
|
|
|
|
|
name: "{{ serveur_ops_paquets }}"
|
|
|
|
|
state: present
|
|
|
|
|
update_cache: true
|
|
|
|
|
when: not ansible_check_mode
|
|
|
|
|
|
|
|
|
|
- name: Créer l'utilisateur d'exploitation
|
|
|
|
|
ansible.builtin.user:
|
|
|
|
|
name: "{{ serveur_ops_utilisateur }}"
|
|
|
|
|
home: "{{ serveur_ops_racine }}"
|
|
|
|
|
shell: /bin/bash
|
|
|
|
|
create_home: true
|
|
|
|
|
system: false
|
|
|
|
|
|
|
|
|
|
- name: Poser les droits de la racine d'exploitation
|
|
|
|
|
ansible.builtin.file:
|
|
|
|
|
path: "{{ serveur_ops_racine }}"
|
|
|
|
|
state: directory
|
|
|
|
|
owner: "{{ serveur_ops_utilisateur }}"
|
|
|
|
|
group: "{{ serveur_ops_utilisateur }}"
|
|
|
|
|
mode: "0750"
|
|
|
|
|
|
|
|
|
|
# L'ENVIRONNEMENT PYTHON EST ISOLÉ, PAS SYSTÈME. Debian gère ansible en paquet, mais la
|
|
|
|
|
# version qu'il propose suit son propre calendrier : reconstruire un écosystème avec un
|
|
|
|
|
# ansible plus récent que celui qui l'a construit, c'est changer la recette sans le dire.
|
|
|
|
|
# Le venv permet d'épingler exactement la famille utilisée par le mainteneur.
|
|
|
|
|
- name: Créer l'environnement Python isolé
|
|
|
|
|
ansible.builtin.command:
|
|
|
|
|
cmd: "python3 -m venv {{ serveur_ops_venv }}"
|
|
|
|
|
creates: "{{ serveur_ops_venv }}/bin/python"
|
|
|
|
|
become: true
|
|
|
|
|
become_user: "{{ serveur_ops_utilisateur }}"
|
|
|
|
|
|
|
|
|
|
- name: Installer Ansible dans l'environnement isolé
|
|
|
|
|
ansible.builtin.pip:
|
|
|
|
|
name:
|
|
|
|
|
- "{{ serveur_ops_ansible }}"
|
|
|
|
|
- "pyyaml"
|
|
|
|
|
virtualenv: "{{ serveur_ops_venv }}"
|
|
|
|
|
state: present
|
|
|
|
|
become: true
|
|
|
|
|
become_user: "{{ serveur_ops_utilisateur }}"
|
|
|
|
|
when: not ansible_check_mode
|
|
|
|
|
register: serveur_ops_pip
|
|
|
|
|
retries: 3
|
|
|
|
|
delay: 6
|
|
|
|
|
until: serveur_ops_pip is succeeded
|
|
|
|
|
|
2026-08-24 18:55:44 -04:00
|
|
|
# LA CONFIANCE, AVANT LE CLONE — et limitee a une seule url.
|
|
|
|
|
#
|
|
|
|
|
# Voir defaults/main.yml : on ne pose pas cette racine dans le magasin systeme. `git
|
|
|
|
|
# config http.<url>.sslCAInfo` ne l'applique qu'aux echanges avec CETTE forge.
|
|
|
|
|
- name: Deposer la racine de la forge amont
|
|
|
|
|
ansible.builtin.copy:
|
|
|
|
|
src: "{{ serveur_ops_forge_amont_ac }}"
|
|
|
|
|
dest: "{{ serveur_ops_forge_amont_ac_depot }}"
|
|
|
|
|
owner: "{{ serveur_ops_utilisateur }}"
|
|
|
|
|
group: "{{ serveur_ops_utilisateur }}"
|
|
|
|
|
mode: "0644"
|
|
|
|
|
when:
|
|
|
|
|
- serveur_ops_forge_amont_ac | length > 0
|
|
|
|
|
- not ansible_check_mode
|
|
|
|
|
|
|
|
|
|
- name: Limiter la confiance a la forge amont, et a elle seule
|
|
|
|
|
community.general.git_config:
|
|
|
|
|
name: "http.{{ serveur_ops_forge_url }}/.sslCAInfo"
|
|
|
|
|
scope: global
|
|
|
|
|
value: "{{ serveur_ops_forge_amont_ac_depot }}"
|
|
|
|
|
become: true
|
|
|
|
|
become_user: "{{ serveur_ops_utilisateur }}"
|
|
|
|
|
when:
|
|
|
|
|
- serveur_ops_forge_amont_ac | length > 0
|
|
|
|
|
- not ansible_check_mode
|
|
|
|
|
|
serveur_ops : la difference entre une archive et une matrice
Un ecosysteme pouvait DETENIR son genome sans savoir l'executer. Le poste
d'exploitation porte Ansible epingle, le genome clone depuis SA PROPRE forge, et
une cle SSH qui n'appartient qu'a lui. Il n'emporte ni la voute ni son mot de
passe : la structure se reconstruit depuis la forge, les secrets depuis la
sauvegarde. Deux sources qu'un meme incident n'atteint pas ensemble.
Une machine neuve traverse tout le moteur sans rien heriter, et revele ce qu'un
etat anterieur masquait. Deux defauts silencieux en sont sortis.
setops_plan_dir pointait le lien `instance` en dur : neuf roles lisaient donc le
plan d'une AUTRE instance. Le plancher de patient 0 portait les FQDN de
Chezlepro, et son edge publiait server_name forge.chezlepro.internal. La
variable suit desormais l'inventaire reellement charge.
Trois instances sur quatre declaraient les SAN d'exposition de leur edge ; la
quatrieme et le modele public ne les avaient pas. La forge de patient 0 etait
donc publiee derriere le certificat auto-signe de Debian, sans que rien ne le
signale -- `git clone` fut le premier a refuser, a juste titre. P42 le reclame
maintenant pour tout ecosysteme qui declare un edge.
Le harnais a ecrit la moitie de ce role : 5 echecs sur la piece neuve, aucun
n'empechait le code de tourner, tous la rendaient invisible a la carte, au
graphe et au lecteur. 42 preuves, 0 echec.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-23 11:58:10 -04:00
|
|
|
# --- LE GÉNOME, DEPUIS SA PROPRE FORGE ---------------------------------------
|
|
|
|
|
#
|
|
|
|
|
# Cloné en anonyme : les dépôts du génome sont lisibles sur la forge de l'écosystème, et
|
|
|
|
|
# le poste n'a donc AUCUN justificatif à détenir pour se reconstruire. C'est délibéré —
|
|
|
|
|
# un secret de moins sur la machine qui en concentre déjà beaucoup.
|
|
|
|
|
#
|
2026-08-24 18:55:44 -04:00
|
|
|
# La confiance TLS vient de `client_pki` quand la forge est celle de CET écosystème
|
|
|
|
|
# (racine step-ca dans le magasin système). Quand elle est celle d'un voisin, elle vient
|
|
|
|
|
# de la tâche ci-dessus — limitée à cette seule url. Sans l'une ou l'autre, `git clone`
|
|
|
|
|
# refuse le certificat, et c'est bien qu'il refuse.
|
serveur_ops : la difference entre une archive et une matrice
Un ecosysteme pouvait DETENIR son genome sans savoir l'executer. Le poste
d'exploitation porte Ansible epingle, le genome clone depuis SA PROPRE forge, et
une cle SSH qui n'appartient qu'a lui. Il n'emporte ni la voute ni son mot de
passe : la structure se reconstruit depuis la forge, les secrets depuis la
sauvegarde. Deux sources qu'un meme incident n'atteint pas ensemble.
Une machine neuve traverse tout le moteur sans rien heriter, et revele ce qu'un
etat anterieur masquait. Deux defauts silencieux en sont sortis.
setops_plan_dir pointait le lien `instance` en dur : neuf roles lisaient donc le
plan d'une AUTRE instance. Le plancher de patient 0 portait les FQDN de
Chezlepro, et son edge publiait server_name forge.chezlepro.internal. La
variable suit desormais l'inventaire reellement charge.
Trois instances sur quatre declaraient les SAN d'exposition de leur edge ; la
quatrieme et le modele public ne les avaient pas. La forge de patient 0 etait
donc publiee derriere le certificat auto-signe de Debian, sans que rien ne le
signale -- `git clone` fut le premier a refuser, a juste titre. P42 le reclame
maintenant pour tout ecosysteme qui declare un edge.
Le harnais a ecrit la moitie de ce role : 5 echecs sur la piece neuve, aucun
n'empechait le code de tourner, tous la rendaient invisible a la carte, au
graphe et au lecteur. 42 preuves, 0 echec.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-23 11:58:10 -04:00
|
|
|
- name: Cloner le génome depuis la forge de l'écosystème
|
|
|
|
|
ansible.builtin.git:
|
|
|
|
|
repo: "{{ serveur_ops_forge_url }}/{{ serveur_ops_forge_organisation }}/{{ item.depot }}.git"
|
|
|
|
|
dest: "{{ serveur_ops_racine }}/{{ item.dest }}"
|
|
|
|
|
version: "{{ item.branche | default('main') }}"
|
|
|
|
|
update: true
|
|
|
|
|
force: false
|
|
|
|
|
loop: "{{ serveur_ops_depots }}"
|
|
|
|
|
loop_control:
|
|
|
|
|
label: "{{ item.depot }} → {{ item.dest }}"
|
|
|
|
|
become: true
|
|
|
|
|
become_user: "{{ serveur_ops_utilisateur }}"
|
|
|
|
|
when: not ansible_check_mode
|
|
|
|
|
register: serveur_ops_clone
|
|
|
|
|
retries: 3
|
|
|
|
|
delay: 6
|
|
|
|
|
until: serveur_ops_clone is succeeded
|
|
|
|
|
|
|
|
|
|
# --- LES COLLECTIONS, SANS DEPENDRE DE GALAXY ---------------------------------
|
|
|
|
|
#
|
|
|
|
|
# UN POSTE D'EXPLOITATION QUI APPELLE galaxy.ansible.com POUR SE CONSTRUIRE N'EST PAS
|
|
|
|
|
# SOUVERAIN. Mesure du 2026-08-23, premier deploiement : `ansible-galaxy collection
|
|
|
|
|
# install` a echoue depuis l'overlay de patient 0 —
|
|
|
|
|
# `SSL: UNEXPECTED_EOF_WHILE_READING` — parce que la frontiere ne laisse pas passer ce
|
|
|
|
|
# flux, et c'est tres bien ainsi. Ouvrir une regle vers un serveur americain pour que
|
|
|
|
|
# l'ecosysteme sache se reconstruire aurait ete la mauvaise reponse.
|
|
|
|
|
#
|
|
|
|
|
# MEME IDIOME QUE serveur_forgejo DEVANT SON PROPRE TIERS : le CONTROLEUR telecharge une
|
|
|
|
|
# fois, dans son cache, puis pousse par SSH. Aucun flux nouveau depuis la cible, et
|
|
|
|
|
# l'artefact devient deployable hors ligne — un poste peut se reconstruire sans internet
|
|
|
|
|
# du tout, ce qui est le sens meme d'une lignee autonome.
|
|
|
|
|
- name: Preparer le cache des collections sur le controleur
|
|
|
|
|
ansible.builtin.file:
|
|
|
|
|
path: "{{ serveur_ops_cache_collections }}"
|
|
|
|
|
state: directory
|
|
|
|
|
mode: "0755"
|
|
|
|
|
delegate_to: localhost
|
|
|
|
|
become: false
|
|
|
|
|
run_once: true
|
|
|
|
|
|
|
|
|
|
# `argv` ET NON `cmd` : le chemin du controleur peut contenir une ESPACE (« Espace
|
|
|
|
|
# Chezlepro/… » chez le mainteneur), et `cmd` la lit comme un separateur d'arguments.
|
|
|
|
|
# Constate le 2026-08-23 : ansible-galaxy recevait « /home/…/Espace » puis
|
|
|
|
|
# « Chezlepro/… » comme deux arguments, et refusait — « positional collection_name arg
|
|
|
|
|
# and --requirements-file are mutually exclusive ». Le message ne parlait pas du tout du
|
|
|
|
|
# vrai probleme.
|
|
|
|
|
- name: Telecharger les collections dans le cache du controleur (une seule fois)
|
|
|
|
|
ansible.builtin.command:
|
|
|
|
|
argv:
|
|
|
|
|
- "ansible-galaxy"
|
|
|
|
|
- "collection"
|
|
|
|
|
- "download"
|
|
|
|
|
- "-r"
|
|
|
|
|
- "{{ serveur_ops_requirements_controleur }}"
|
|
|
|
|
- "-p"
|
|
|
|
|
- "{{ serveur_ops_cache_collections }}"
|
|
|
|
|
creates: "{{ serveur_ops_cache_collections }}/requirements.yml"
|
|
|
|
|
delegate_to: localhost
|
|
|
|
|
become: false
|
|
|
|
|
run_once: true
|
|
|
|
|
when: not ansible_check_mode
|
|
|
|
|
|
|
|
|
|
- name: Deposer les collections sur le poste
|
2026-08-24 15:50:37 -04:00
|
|
|
register: serveur_ops_depot_collections
|
serveur_ops : la difference entre une archive et une matrice
Un ecosysteme pouvait DETENIR son genome sans savoir l'executer. Le poste
d'exploitation porte Ansible epingle, le genome clone depuis SA PROPRE forge, et
une cle SSH qui n'appartient qu'a lui. Il n'emporte ni la voute ni son mot de
passe : la structure se reconstruit depuis la forge, les secrets depuis la
sauvegarde. Deux sources qu'un meme incident n'atteint pas ensemble.
Une machine neuve traverse tout le moteur sans rien heriter, et revele ce qu'un
etat anterieur masquait. Deux defauts silencieux en sont sortis.
setops_plan_dir pointait le lien `instance` en dur : neuf roles lisaient donc le
plan d'une AUTRE instance. Le plancher de patient 0 portait les FQDN de
Chezlepro, et son edge publiait server_name forge.chezlepro.internal. La
variable suit desormais l'inventaire reellement charge.
Trois instances sur quatre declaraient les SAN d'exposition de leur edge ; la
quatrieme et le modele public ne les avaient pas. La forge de patient 0 etait
donc publiee derriere le certificat auto-signe de Debian, sans que rien ne le
signale -- `git clone` fut le premier a refuser, a juste titre. P42 le reclame
maintenant pour tout ecosysteme qui declare un edge.
Le harnais a ecrit la moitie de ce role : 5 echecs sur la piece neuve, aucun
n'empechait le code de tourner, tous la rendaient invisible a la carte, au
graphe et au lecteur. 42 preuves, 0 echec.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-23 11:58:10 -04:00
|
|
|
ansible.builtin.copy:
|
|
|
|
|
src: "{{ serveur_ops_cache_collections }}/"
|
|
|
|
|
dest: "{{ serveur_ops_racine }}/.collections-hors-ligne/"
|
|
|
|
|
owner: "{{ serveur_ops_utilisateur }}"
|
|
|
|
|
group: "{{ serveur_ops_utilisateur }}"
|
|
|
|
|
mode: "0644"
|
|
|
|
|
directory_mode: "0755"
|
|
|
|
|
when: not ansible_check_mode
|
|
|
|
|
|
|
|
|
|
# `chdir` OBLIGATOIRE : le `requirements.yml` produit par `collection download` nomme les
|
|
|
|
|
# archives en RELATIF (`community-postgresql-4.2.0.tar.gz`), et ansible-galaxy les cherche
|
|
|
|
|
# depuis le repertoire COURANT, pas depuis celui du fichier. Sans chdir : « Could not find
|
|
|
|
|
# community-postgresql-4.2.0.tar.gz » alors que l'archive est bien la, a cote.
|
|
|
|
|
- name: Installer les collections depuis le depot local (hors ligne)
|
|
|
|
|
ansible.builtin.command:
|
|
|
|
|
cmd: >-
|
|
|
|
|
{{ serveur_ops_venv }}/bin/ansible-galaxy collection install
|
|
|
|
|
-r requirements.yml
|
|
|
|
|
-p {{ serveur_ops_racine }}/.ansible/collections
|
|
|
|
|
chdir: "{{ serveur_ops_racine }}/.collections-hors-ligne"
|
2026-08-24 15:50:37 -04:00
|
|
|
# LE GARDE-FOU SUIVAIT LA MAUVAISE CHOSE (2026-08-24). Il etait `creates: …/community/general` :
|
|
|
|
|
# une collection AJOUTEE a requirements.yml n'aurait jamais ete installee, puisque le
|
|
|
|
|
# repertoire temoin existait deja. Le runner serait reste en retard sur le moteur, en
|
|
|
|
|
# silence. On suit desormais le DEPOT des archives : si les collections deposees
|
|
|
|
|
# changent, on reinstalle.
|
|
|
|
|
changed_when: true
|
serveur_ops : la difference entre une archive et une matrice
Un ecosysteme pouvait DETENIR son genome sans savoir l'executer. Le poste
d'exploitation porte Ansible epingle, le genome clone depuis SA PROPRE forge, et
une cle SSH qui n'appartient qu'a lui. Il n'emporte ni la voute ni son mot de
passe : la structure se reconstruit depuis la forge, les secrets depuis la
sauvegarde. Deux sources qu'un meme incident n'atteint pas ensemble.
Une machine neuve traverse tout le moteur sans rien heriter, et revele ce qu'un
etat anterieur masquait. Deux defauts silencieux en sont sortis.
setops_plan_dir pointait le lien `instance` en dur : neuf roles lisaient donc le
plan d'une AUTRE instance. Le plancher de patient 0 portait les FQDN de
Chezlepro, et son edge publiait server_name forge.chezlepro.internal. La
variable suit desormais l'inventaire reellement charge.
Trois instances sur quatre declaraient les SAN d'exposition de leur edge ; la
quatrieme et le modele public ne les avaient pas. La forge de patient 0 etait
donc publiee derriere le certificat auto-signe de Debian, sans que rien ne le
signale -- `git clone` fut le premier a refuser, a juste titre. P42 le reclame
maintenant pour tout ecosysteme qui declare un edge.
Le harnais a ecrit la moitie de ce role : 5 echecs sur la piece neuve, aucun
n'empechait le code de tourner, tous la rendaient invisible a la carte, au
graphe et au lecteur. 42 preuves, 0 echec.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-23 11:58:10 -04:00
|
|
|
become: true
|
|
|
|
|
become_user: "{{ serveur_ops_utilisateur }}"
|
2026-08-24 15:50:37 -04:00
|
|
|
# DEUX `when` SUR UNE MEME TACHE, C'EST UN SEUL — LE DERNIER (2026-08-24). En ajoutant
|
|
|
|
|
# la condition sur le depot, j'ai laisse celle du check-mode juste en dessous : YAML
|
|
|
|
|
# garde la derniere cle et jette l'autre, en silence. `ansible-lint` l'a vu ; personne
|
|
|
|
|
# d'autre ne l'aurait vu. Les conditions vont donc dans UNE liste.
|
|
|
|
|
when:
|
|
|
|
|
- serveur_ops_depot_collections is changed
|
|
|
|
|
- not ansible_check_mode
|
serveur_ops : la difference entre une archive et une matrice
Un ecosysteme pouvait DETENIR son genome sans savoir l'executer. Le poste
d'exploitation porte Ansible epingle, le genome clone depuis SA PROPRE forge, et
une cle SSH qui n'appartient qu'a lui. Il n'emporte ni la voute ni son mot de
passe : la structure se reconstruit depuis la forge, les secrets depuis la
sauvegarde. Deux sources qu'un meme incident n'atteint pas ensemble.
Une machine neuve traverse tout le moteur sans rien heriter, et revele ce qu'un
etat anterieur masquait. Deux defauts silencieux en sont sortis.
setops_plan_dir pointait le lien `instance` en dur : neuf roles lisaient donc le
plan d'une AUTRE instance. Le plancher de patient 0 portait les FQDN de
Chezlepro, et son edge publiait server_name forge.chezlepro.internal. La
variable suit desormais l'inventaire reellement charge.
Trois instances sur quatre declaraient les SAN d'exposition de leur edge ; la
quatrieme et le modele public ne les avaient pas. La forge de patient 0 etait
donc publiee derriere le certificat auto-signe de Debian, sans que rien ne le
signale -- `git clone` fut le premier a refuser, a juste titre. P42 le reclame
maintenant pour tout ecosysteme qui declare un edge.
Le harnais a ecrit la moitie de ce role : 5 echecs sur la piece neuve, aucun
n'empechait le code de tourner, tous la rendaient invisible a la carte, au
graphe et au lecteur. 42 preuves, 0 echec.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-23 11:58:10 -04:00
|
|
|
|
|
|
|
|
# LES DEUX SYMLINKS (D-80). `instance` dit QUEL tenant on pilote. Le poste en pose un par
|
|
|
|
|
# défaut ; l'exploitant le bascule comme sur le poste du mainteneur.
|
|
|
|
|
- name: Désigner l'instance pilotée par défaut
|
|
|
|
|
ansible.builtin.file:
|
|
|
|
|
src: "{{ serveur_ops_racine }}/{{ serveur_ops_instance }}"
|
|
|
|
|
dest: >-
|
|
|
|
|
{{ serveur_ops_racine }}/{{ (serveur_ops_depots | selectattr('role', 'eq', 'moteur') | first).dest }}/instance
|
|
|
|
|
state: link
|
|
|
|
|
owner: "{{ serveur_ops_utilisateur }}"
|
|
|
|
|
group: "{{ serveur_ops_utilisateur }}"
|
|
|
|
|
force: true
|
|
|
|
|
when: not ansible_check_mode
|
|
|
|
|
|
2026-08-23 12:24:28 -04:00
|
|
|
# LE SECOND SYMLINK. Sans lui, le poste sait configurer des machines qui existent ; il ne
|
|
|
|
|
# sait pas en creer, faute de savoir sur quelle fabric les poser. C'est la difference
|
|
|
|
|
# entre exploiter et engendrer.
|
|
|
|
|
- name: Désigner la fabric sur laquelle l'écosystème repose
|
|
|
|
|
ansible.builtin.file:
|
|
|
|
|
src: "{{ serveur_ops_racine }}/{{ serveur_ops_underlay }}/underlay.yml"
|
|
|
|
|
dest: >-
|
|
|
|
|
{{ serveur_ops_racine }}/{{ (serveur_ops_depots | selectattr('role', 'eq', 'moteur') | first).dest }}/underlay.yml
|
|
|
|
|
state: link
|
|
|
|
|
owner: "{{ serveur_ops_utilisateur }}"
|
|
|
|
|
group: "{{ serveur_ops_utilisateur }}"
|
|
|
|
|
force: true
|
|
|
|
|
when:
|
|
|
|
|
- serveur_ops_underlay | length > 0
|
|
|
|
|
- not ansible_check_mode
|
|
|
|
|
|
serveur_ops : la difference entre une archive et une matrice
Un ecosysteme pouvait DETENIR son genome sans savoir l'executer. Le poste
d'exploitation porte Ansible epingle, le genome clone depuis SA PROPRE forge, et
une cle SSH qui n'appartient qu'a lui. Il n'emporte ni la voute ni son mot de
passe : la structure se reconstruit depuis la forge, les secrets depuis la
sauvegarde. Deux sources qu'un meme incident n'atteint pas ensemble.
Une machine neuve traverse tout le moteur sans rien heriter, et revele ce qu'un
etat anterieur masquait. Deux defauts silencieux en sont sortis.
setops_plan_dir pointait le lien `instance` en dur : neuf roles lisaient donc le
plan d'une AUTRE instance. Le plancher de patient 0 portait les FQDN de
Chezlepro, et son edge publiait server_name forge.chezlepro.internal. La
variable suit desormais l'inventaire reellement charge.
Trois instances sur quatre declaraient les SAN d'exposition de leur edge ; la
quatrieme et le modele public ne les avaient pas. La forge de patient 0 etait
donc publiee derriere le certificat auto-signe de Debian, sans que rien ne le
signale -- `git clone` fut le premier a refuser, a juste titre. P42 le reclame
maintenant pour tout ecosysteme qui declare un edge.
Le harnais a ecrit la moitie de ce role : 5 echecs sur la piece neuve, aucun
n'empechait le code de tourner, tous la rendaient invisible a la carte, au
graphe et au lecteur. 42 preuves, 0 echec.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-23 11:58:10 -04:00
|
|
|
# --- LA CLÉ DU POSTE ---------------------------------------------------------
|
|
|
|
|
#
|
|
|
|
|
# Le poste se fabrique sa propre paire, distincte de celle du mainteneur. Deux
|
|
|
|
|
# exploitants, deux clés : on peut révoquer l'un sans couper l'autre — et l'accès du
|
|
|
|
|
# poste se lit dans les `authorized_keys` de la flotte, au lieu de se confondre avec
|
|
|
|
|
# celui d'un humain.
|
|
|
|
|
#
|
|
|
|
|
# `ssh-keygen` plutôt que `community.crypto.openssh_keypair` : le dépôt ne requiert que
|
|
|
|
|
# `community.postgresql` et `community.general`, et fabriquer une paire de clés ne
|
|
|
|
|
# justifie pas d'imposer une collection de plus à tout écosystème qui déploie un poste.
|
|
|
|
|
- name: Assurer le répertoire SSH du poste
|
|
|
|
|
ansible.builtin.file:
|
|
|
|
|
path: "{{ serveur_ops_racine }}/.ssh"
|
|
|
|
|
state: directory
|
|
|
|
|
owner: "{{ serveur_ops_utilisateur }}"
|
|
|
|
|
group: "{{ serveur_ops_utilisateur }}"
|
|
|
|
|
mode: "0700"
|
|
|
|
|
|
|
|
|
|
- name: Fabriquer la clé SSH du poste
|
|
|
|
|
ansible.builtin.command:
|
|
|
|
|
cmd: >-
|
|
|
|
|
ssh-keygen -t {{ serveur_ops_cle_type }} -N ''
|
|
|
|
|
-C "setops@{{ inventory_hostname }}.{{ domaine_interne }}"
|
|
|
|
|
-f {{ serveur_ops_racine }}/.ssh/id_{{ serveur_ops_cle_type }}
|
|
|
|
|
creates: "{{ serveur_ops_racine }}/.ssh/id_{{ serveur_ops_cle_type }}"
|
|
|
|
|
become: true
|
|
|
|
|
become_user: "{{ serveur_ops_utilisateur }}"
|
|
|
|
|
when:
|
|
|
|
|
- serveur_ops_cle_generer | bool
|
|
|
|
|
- not ansible_check_mode
|
|
|
|
|
register: serveur_ops_cle
|
|
|
|
|
|
|
|
|
|
- name: Relire la clé publique du poste
|
|
|
|
|
ansible.builtin.slurp:
|
|
|
|
|
src: "{{ serveur_ops_racine }}/.ssh/id_{{ serveur_ops_cle_type }}.pub"
|
|
|
|
|
register: serveur_ops_pub
|
|
|
|
|
when:
|
|
|
|
|
- serveur_ops_cle_generer | bool
|
|
|
|
|
- not ansible_check_mode
|
|
|
|
|
|
|
|
|
|
# ÉCRIRE, PUIS RELIRE (D-68) — et rendre le résultat EXPLOITABLE. Cette clé ne sert à
|
|
|
|
|
# rien tant qu'elle n'est pas autorisée sur la flotte : on l'affiche pour que l'exploitant
|
|
|
|
|
# la reprenne dans les intrants, au lieu de la laisser dormir sur le disque.
|
|
|
|
|
- name: La clé publique à autoriser sur la flotte
|
|
|
|
|
ansible.builtin.debug:
|
|
|
|
|
msg:
|
|
|
|
|
- "Clé publique du poste d'exploitation — à ajouter aux intrants SSH du plan :"
|
|
|
|
|
- "{{ serveur_ops_pub.content | b64decode | trim }}"
|
|
|
|
|
when:
|
|
|
|
|
- serveur_ops_cle_generer | bool
|
|
|
|
|
- not ansible_check_mode
|
|
|
|
|
|
|
|
|
|
- name: Déposer le mode d'emploi sur le poste
|
|
|
|
|
ansible.builtin.template:
|
|
|
|
|
src: LISEZ-MOI.md.j2
|
|
|
|
|
dest: "{{ serveur_ops_racine }}/LISEZ-MOI.md"
|
|
|
|
|
owner: "{{ serveur_ops_utilisateur }}"
|
|
|
|
|
group: "{{ serveur_ops_utilisateur }}"
|
|
|
|
|
mode: "0644"
|