Chaque role proprietaire (AC, bases, annuaire, Nextcloud, rspamd/DKIM, courriel, forge, web) remet son etat au moment ou il le creerait neuf, depuis le dernier instantane anterieur a la naissance de la machine. La sauvegarde refuse de deposer tant qu'un etat d'avant attend. Outil de noeud setops-restaurer ; cibles sauvegarder-maintenant, restauration-etat, restauration-renoncer ; test_restauration. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
225 lines
8.6 KiB
YAML
225 lines
8.6 KiB
YAML
---
|
|
- name: Exiger les secrets de l'AC (Vault)
|
|
ansible.builtin.assert:
|
|
that:
|
|
- serveur_step_ca_password | length > 0
|
|
- serveur_step_ca_provisioner_password | length > 0
|
|
fail_msg: >-
|
|
serveur_step_ca_password et serveur_step_ca_provisioner_password
|
|
sont requis (a fournir via Ansible Vault).
|
|
|
|
- name: Assurer le repertoire des trousseaux apt
|
|
ansible.builtin.file:
|
|
path: /etc/apt/keyrings
|
|
state: directory
|
|
owner: root
|
|
group: root
|
|
mode: "0755"
|
|
|
|
# LA GARDE « RECUPEREE UNE FOIS » A DISPARU AVEC CE QU'ELLE GARDAIT (2026-08-30).
|
|
#
|
|
# Elle evitait de recontacter le fournisseur a chaque passage — soixante-dix allers-retours
|
|
# externes pour des cles deja installees (arbitrage du 2026-08-09). La cle etant desormais
|
|
# VERSIONNEE, il n'y a plus d'aller-retour a eviter : `copy` ne sort pas, et son
|
|
# idempotence vient de la comparaison d'empreintes, pas d'un `stat` qu'on ecrit soi-meme.
|
|
#
|
|
# Le meme arbitrage est donc honore plus completement : la plateforme ne depend plus du
|
|
# tout de serveurs etrangers pour redeployer ce qu'elle possede deja.
|
|
|
|
# LA CLE DE SIGNATURE EST VERSIONNEE, PLUS TELECHARGEE (2026-08-30).
|
|
#
|
|
# Elle etait tiree de `packages.smallstep.com` par son NOM. Un tenant n'a pas de DNS
|
|
# sortant — il resout chez lui, sa requete ne traverse jamais la frontiere — et
|
|
# `get_url` n'a pas de mandataire, la ou `apt` s'en sort par le cache qui resout a sa
|
|
# place. Mesure sur `infra-pki-01`, premiere machine a porter l'autorite de Chezlepro :
|
|
#
|
|
# Request failed: <urlopen error [Errno -3] Echec temporaire dans la resolution du nom>
|
|
#
|
|
# Les cinq reprises de l'ancienne version ne pouvaient rien : elles etaient ecrites pour
|
|
# un serveur INTERMITTENT (mesure du 2026-08-23), pas pour une resolution fermee. Une
|
|
# reprise ne repare que ce qui est passager.
|
|
#
|
|
# MEME IDIOME QUE LES COLLECTIONS ET LES ROUES : le depot porte, la cible n'ouvre rien.
|
|
# C'est ce qui rend une lignee reproductible sans Internet. Empreinte, raison et
|
|
# procedure de mise a jour dans `files/README-cle-smallstep.md`.
|
|
#
|
|
# `serveur_step_ca_depot_cle_url` reste declaree : elle documente la provenance et sert
|
|
# a rafraichir le fichier depuis un poste qui a le DNS. Elle n'est plus lue au deploiement.
|
|
- name: Poser la cle de signature Smallstep (versionnee, aucun appel sortant)
|
|
ansible.builtin.copy:
|
|
src: smallstep-repo-signing-key.asc
|
|
dest: "{{ serveur_step_ca_depot_cle_fichier }}"
|
|
owner: root
|
|
group: root
|
|
mode: "0644"
|
|
|
|
- name: Ajouter le depot apt Smallstep
|
|
ansible.builtin.template:
|
|
src: smallstep.sources.j2
|
|
dest: /etc/apt/sources.list.d/smallstep.sources
|
|
owner: root
|
|
group: root
|
|
mode: "0644"
|
|
|
|
- name: Installer step-ca et step-cli
|
|
when: not ansible_check_mode # dry-run : le depot Smallstep n'est pas reellement ajoute
|
|
ansible.builtin.apt:
|
|
name: "{{ serveur_step_ca_paquets }}"
|
|
state: present
|
|
update_cache: true
|
|
|
|
- name: Creer l'utilisateur systeme step
|
|
ansible.builtin.user:
|
|
name: "{{ serveur_step_ca_utilisateur }}"
|
|
system: true
|
|
home: "{{ serveur_step_ca_steppath }}"
|
|
create_home: false
|
|
shell: /usr/sbin/nologin
|
|
|
|
# L'AC NE RENAIT PAS SI ELLE A DEJA VECU (2026-09-30).
|
|
#
|
|
# `step ca init` fabriquait une racine neuve a chaque reconstruction : toute confiance
|
|
# accordee a l'ancienne (postes, navigateurs, autres ecosystemes) tombait sans bruit.
|
|
# Technolibre a change de racine le 2026-09-30, Chezlepro le 2026-09-13.
|
|
#
|
|
# C'est ICI, avant l'init, que l'AC d'une incarnation precedente doit revenir : ensuite,
|
|
# toute la flotte s'enrole aupres d'elle comme d'habitude. Plus tard, il faudrait
|
|
# reenroler chaque machine.
|
|
- name: L'autorite a-t-elle deja ete initialisee ?
|
|
ansible.builtin.stat:
|
|
path: "{{ serveur_step_ca_steppath }}/config/ca.json"
|
|
register: serveur_step_ca_ca_json
|
|
|
|
- name: Restauration — l'autorite d'une incarnation precedente ?
|
|
ansible.builtin.include_role:
|
|
name: client_backup
|
|
tasks_from: restaurer.yml
|
|
vars:
|
|
client_backup_restaurer_jeu: serveur_step_ca
|
|
client_backup_restaurer_vierge: "{{ not serveur_step_ca_ca_json.stat.exists }}"
|
|
|
|
- name: Restauration — remettre l'autorite (racine, intermediaire, base des emissions)
|
|
changed_when: true
|
|
ansible.builtin.command:
|
|
argv:
|
|
- /usr/local/sbin/setops-restaurer
|
|
- fichiers
|
|
- --instantane
|
|
- "{{ client_backup_restauration.instantane }}"
|
|
- --proprietaire
|
|
- "{{ serveur_step_ca_utilisateur }}:{{ serveur_step_ca_utilisateur }}"
|
|
- "{{ serveur_step_ca_steppath }}"
|
|
when: client_backup_restauration.etat == 'a_restaurer'
|
|
|
|
# LES CLES SONT CHIFFREES PAR LE MOT DE PASSE DE L'EPOQUE. La tache suivante reecrit
|
|
# `password.txt` depuis la voute : si la voute a change depuis, step-ca ne demarrerait
|
|
# plus, et l'erreur parlerait de dechiffrement, pas de restauration.
|
|
- name: Restauration — lire les mots de passe restaures
|
|
ansible.builtin.slurp:
|
|
src: "{{ serveur_step_ca_steppath }}/{{ item }}"
|
|
loop: [password.txt, provisioner_password.txt]
|
|
register: serveur_step_ca_mdp_restaures
|
|
no_log: true
|
|
when: client_backup_restauration.etat == 'a_restaurer'
|
|
|
|
- name: Restauration — la voute ouvre-t-elle encore ces cles ?
|
|
ansible.builtin.assert:
|
|
that:
|
|
- (serveur_step_ca_mdp_restaures.results[0].content | b64decode) == serveur_step_ca_password
|
|
- (serveur_step_ca_mdp_restaures.results[1].content | b64decode) == serveur_step_ca_provisioner_password
|
|
fail_msg: >-
|
|
L'AC restauree ({{ client_backup_restauration.instantane }}) est chiffree par un mot
|
|
de passe que la voute ne porte plus. Remettre les anciennes valeurs de
|
|
vault_step_ca_password / provisioner dans la voute, ou renoncer a cette AC.
|
|
no_log: true
|
|
when: client_backup_restauration.etat == 'a_restaurer'
|
|
|
|
- name: Restauration — acter l'autorite remise
|
|
ansible.builtin.include_role:
|
|
name: client_backup
|
|
tasks_from: acter.yml
|
|
vars:
|
|
client_backup_acter_etat: restaure
|
|
when: client_backup_restauration.etat == 'a_restaurer'
|
|
|
|
- name: Creer le repertoire STEPPATH
|
|
ansible.builtin.file:
|
|
path: "{{ serveur_step_ca_steppath }}"
|
|
state: directory
|
|
owner: "{{ serveur_step_ca_utilisateur }}"
|
|
group: "{{ serveur_step_ca_utilisateur }}"
|
|
mode: "0700"
|
|
|
|
- name: Deployer le mot de passe de l'AC
|
|
ansible.builtin.copy:
|
|
content: "{{ serveur_step_ca_password }}"
|
|
dest: "{{ serveur_step_ca_steppath }}/password.txt"
|
|
owner: "{{ serveur_step_ca_utilisateur }}"
|
|
group: "{{ serveur_step_ca_utilisateur }}"
|
|
mode: "0600"
|
|
no_log: true
|
|
notify: Redemarrer step-ca
|
|
|
|
- name: Deployer le mot de passe du provisioner
|
|
ansible.builtin.copy:
|
|
content: "{{ serveur_step_ca_provisioner_password }}"
|
|
dest: "{{ serveur_step_ca_steppath }}/provisioner_password.txt"
|
|
owner: "{{ serveur_step_ca_utilisateur }}"
|
|
group: "{{ serveur_step_ca_utilisateur }}"
|
|
mode: "0600"
|
|
no_log: true
|
|
|
|
- name: Initialiser l'autorite de certification (une seule fois)
|
|
when: not ansible_check_mode # dry-run : le binaire step n'est pas encore installe
|
|
ansible.builtin.command:
|
|
cmd: >-
|
|
step ca init
|
|
--deployment-type standalone
|
|
--name "{{ serveur_step_ca_nom }}"
|
|
--dns "{{ serveur_step_ca_dns }}"
|
|
--address "{{ serveur_step_ca_adresse }}"
|
|
--provisioner "{{ serveur_step_ca_provisioner }}"
|
|
--password-file {{ serveur_step_ca_steppath }}/password.txt
|
|
--provisioner-password-file {{ serveur_step_ca_steppath }}/provisioner_password.txt
|
|
{{ '--acme' if serveur_step_ca_acme | bool else '' }}
|
|
creates: "{{ serveur_step_ca_steppath }}/config/ca.json"
|
|
become: true
|
|
become_user: "{{ serveur_step_ca_utilisateur }}"
|
|
environment:
|
|
STEPPATH: "{{ serveur_step_ca_steppath }}"
|
|
|
|
- name: Deployer l'unite systemd step-ca
|
|
ansible.builtin.template:
|
|
src: step-ca.service.j2
|
|
dest: /etc/systemd/system/step-ca.service
|
|
owner: root
|
|
group: root
|
|
mode: "0644"
|
|
notify: Redemarrer step-ca
|
|
|
|
- name: Activer et demarrer step-ca
|
|
when: not ansible_check_mode
|
|
ansible.builtin.systemd:
|
|
name: "{{ serveur_step_ca_service }}"
|
|
enabled: true
|
|
state: started
|
|
daemon_reload: true
|
|
|
|
# --- Sonde de supervision (docs/supervision-conception.md) --------------------------
|
|
# Le role qui possede la verite depose sa propre sonde ; le porteur (`client_sante`) la
|
|
# fait tourner et pousse le verdict, sans savoir ce qu'elle mesure.
|
|
- name: Assurer le repertoire des sondes de supervision
|
|
ansible.builtin.file:
|
|
path: /usr/local/lib/setops/sondes
|
|
state: directory
|
|
owner: root
|
|
group: root
|
|
mode: "0755"
|
|
|
|
- name: Deposer la sonde « autorite »
|
|
ansible.builtin.template:
|
|
src: sonde-autorite.sh.j2
|
|
dest: /usr/local/lib/setops/sondes/autorite.sh
|
|
owner: root
|
|
group: root
|
|
mode: "0750"
|