--- # L'empreinte du root CA est la SOURCE DE VÉRITÉ de l'autorité elle-même : on la # dérive à chaud (robuste au from-zero — une AC régénérée a une empreinte neuve). # `client_pki_ca_fingerprint_override` permet d'épingler explicitement si besoin. - name: Dériver l'empreinte du root CA depuis l'autorité ansible.builtin.command: cmd: "step certificate fingerprint {{ serveur_step_ca_steppath | default('/etc/step-ca') }}/certs/root_ca.crt" delegate_to: "{{ groups['serveur_step_ca'][0] }}" changed_when: false check_mode: false register: client_pki_fingerprint_ac - name: Retenir l'empreinte (dérivée de l'AC, sauf override explicite) ansible.builtin.set_fact: client_pki_ca_fingerprint: "{{ client_pki_ca_fingerprint_override | default(client_pki_fingerprint_ac.stdout | trim, true) }}" - name: Exiger l'empreinte AC et le mot de passe provisioner (Vault) ansible.builtin.assert: that: - client_pki_ca_fingerprint | length > 0 - client_pki_provisioner_password | length > 0 fail_msg: >- Empreinte du root CA indisponible (step-ca joignable et déployé ?) ; client_pki_provisioner_password requis (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" - name: Telecharger la cle de signature Smallstep ansible.builtin.get_url: url: "{{ client_pki_depot_cle_url }}" dest: "{{ client_pki_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-cli ansible.builtin.apt: name: "{{ client_pki_paquets }}" state: present update_cache: true - name: Creer le repertoire STEPPATH des certificats ansible.builtin.file: path: "{{ client_pki_steppath }}/certs" state: directory owner: root group: root mode: "0755" - name: Deployer le mot de passe du provisioner ansible.builtin.copy: content: "{{ client_pki_provisioner_password }}" dest: "{{ client_pki_steppath }}/provisioner.pass" owner: root group: root mode: "0600" no_log: true # L'AUTORITE EST UN CAS A PART, mais pas une exception. Elle n'a pas a « s'enroler » # aupres d'elle-meme : sa racine est deja sur son disque, et un bootstrap la ferait # aller la chercher par le reseau, chez elle, en verifiant une empreinte qu'elle vient # de produire. Elle a en revanche besoin de CERTIFICATS comme tout le monde — sans quoi # ses propres services (node_exporter) restent en clair, et `client_metrique` echoue. # # La distinction est donc : pas d'enrolement, mais emission locale. C'est ce qui permet # de retirer l'exemption de `client_pki` sans contredire « l'AC est la source de la # confiance » — elle l'est, et c'est precisement pourquoi elle peut se signer elle-meme. - name: Reconnaitre l'hote qui PORTE l'autorite ansible.builtin.set_fact: client_pki_est_autorite: "{{ inventory_hostname in (groups['serveur_step_ca'] | default([])) }}" - name: Etablir la confiance dans l'AC interne (bootstrap + installation racine) ansible.builtin.command: cmd: >- step ca bootstrap --ca-url {{ client_pki_ca_url }} --fingerprint {{ client_pki_ca_fingerprint }} --install --force creates: "{{ client_pki_steppath }}/certs/root_ca.crt" environment: STEPPATH: "{{ client_pki_steppath }}" when: not client_pki_est_autorite | bool - name: Poser la racine depuis le disque local (l'autorite ne s'enrole pas aupres d'elle-meme) ansible.builtin.copy: src: "{{ serveur_step_ca_steppath | default('/etc/step-ca') }}/certs/root_ca.crt" dest: "{{ client_pki_steppath }}/certs/root_ca.crt" remote_src: true owner: root group: root mode: "0644" when: client_pki_est_autorite | bool - name: Rendre le certificat racine lisible par tous (cert public, requis par les clients TLS) ansible.builtin.file: path: "{{ client_pki_steppath }}/certs/root_ca.crt" mode: "0644" - name: Lire les SAN du certificat d'hote existant (detection de derive) ansible.builtin.command: cmd: "openssl x509 -in {{ client_pki_cert }} -noout -ext subjectAltName" register: client_pki_san_actuels changed_when: false failed_when: false # Re-emet si le cert est absent OU si un SAN voulu manque (ex: nouvelle exposition # ajoutee au plan -> client_pki_sans mis a jour). Plus de garde 'creates' aveugle. - name: Obtenir / re-emettre le certificat d'hote (absent ou SAN derives) ansible.builtin.command: # `--ca-url` et `--root` EXPLICITES : sur un hote ordinaire ils sont redondants avec # le `defaults.json` qu'ecrit `step ca bootstrap`, mais l'autorite ne bootstrape pas # — elle n'aurait donc aucune de ces deux valeurs. Les nommer ici vaut mieux que de # dependre d'un fichier ecrit par une etape qu'on saute volontairement. cmd: >- step ca certificate {{ client_pki_nom_cert }} {{ client_pki_cert }} {{ client_pki_cle }} --ca-url {{ client_pki_ca_url }} --root {{ client_pki_steppath }}/certs/root_ca.crt --provisioner {{ client_pki_provisioner }} --provisioner-password-file {{ client_pki_steppath }}/provisioner.pass {% for s in client_pki_sans | select | unique %}--san {{ s }} {% endfor %} --force environment: STEPPATH: "{{ client_pki_steppath }}" when: >- client_pki_san_actuels.rc != 0 or (client_pki_sans | select | unique | reject('equalto', '') | reject('in', client_pki_san_actuels.stdout | default('')) | list | length > 0) changed_when: true notify: Recharger les consommateurs du cert - name: Deployer l'unite systemd de renouvellement ansible.builtin.template: src: cert-renewer@.service.j2 dest: /etc/systemd/system/cert-renewer@.service owner: root group: root mode: "0644" notify: Recharger systemd - name: Deployer le minuteur de renouvellement ansible.builtin.template: src: cert-renewer@.timer.j2 dest: /etc/systemd/system/cert-renewer@.timer owner: root group: root mode: "0644" notify: Recharger systemd - name: Activer le renouvellement automatique du certificat d'hote ansible.builtin.systemd: name: "cert-renewer@{{ client_pki_nom_cert }}.timer" enabled: true state: started daemon_reload: true