Set-OPS-Public/roles/serveur_step_ca/tasks/main.yml
Daniel Allaire 8a9da0c31a restauration : la reconstruction remet l'etat de l'incarnation precedente
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>
2026-09-30 02:39:22 -04:00

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"