--- - 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: # # 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"