--- - name: Exiger les intrants du runner de site ansible.builtin.assert: that: - serveur_ops_site_depot | length > 0 - (not (serveur_ops_site_voute_deposer | bool)) or (serveur_ops_site_voute_source | length > 0) fail_msg: >- serveur_ops_site exige `serveur_ops_site_depot` (le dossier du dépôt SITE chez le runner, cloné par serveur_ops) et, si le dépôt de la voûte est demandé, `serveur_ops_site_voute_source` (le chemin de `underlay.vault.yml` sur le contrôleur). - name: Le dépôt du SITE est-il bien là ? ansible.builtin.stat: path: "{{ serveur_ops_site_racine }}/{{ serveur_ops_site_depot }}/underlay.yml" register: serveur_ops_site_carte - name: Refuser si la carte de la fabric manque ansible.builtin.assert: that: - serveur_ops_site_carte.stat.exists fail_msg: >- {{ serveur_ops_site_racine }}/{{ serveur_ops_site_depot }}/underlay.yml est absent. Déclarer ce dépôt dans `serveur_ops_depots` (role: hebergeur) et rejouer serveur_ops : un runner de site sans carte ne sait pas sur quoi il matérialise. when: not ansible_check_mode # LES CLÉS DU MONDE PHYSIQUE, DE DROIT ET NON PAR EMPRUNT. # # `decrypt: no` : voir defaults/main.yml. Le fichier reste chiffré ; seul le mot de passe, # tapé à l'exécution, l'ouvre. - name: Déposer la voûte du SITE (chiffrée) ansible.builtin.copy: src: "{{ serveur_ops_site_voute_source }}" dest: "{{ serveur_ops_site_racine }}/{{ serveur_ops_site_depot }}/underlay.vault.yml" owner: "{{ serveur_ops_site_utilisateur }}" group: "{{ serveur_ops_site_utilisateur }}" mode: "0600" decrypt: false when: - serveur_ops_site_voute_deposer | bool - not ansible_check_mode # ÉCRIRE, PUIS RELIRE (D-68). Une voûte déchiffrée par accident est une fuite silencieuse : # le fichier existe, le rôle se dit satisfait, et les clés du cluster dorment en clair. - name: Relire l'en-tête de la voûte déposée ansible.builtin.command: cmd: "head -c 21 {{ serveur_ops_site_racine }}/{{ serveur_ops_site_depot }}/underlay.vault.yml" register: serveur_ops_site_entete changed_when: false when: - serveur_ops_site_voute_deposer | bool - not ansible_check_mode - name: Exiger que la voûte déposée soit CHIFFRÉE ansible.builtin.assert: that: - "'$ANSIBLE_VAULT' in serveur_ops_site_entete.stdout" fail_msg: >- La voûte déposée n'est PAS chiffrée — elle a été déchiffrée en transit. Vérifier `decrypt: false` sur la copie. Détruire le fichier au shred et considérer les justificatifs du cluster comme exposés. when: - serveur_ops_site_voute_deposer | bool - not ansible_check_mode # --- ARMER LE RUNNER --------------------------------------------------------- # # Ce qui suit ne se declenche que si un humain l'a demande (serveur_ops_site_cle_deposer). - name: Exiger une source pour la cle de la voute ansible.builtin.assert: that: - serveur_ops_site_cle_source | length > 0 fail_msg: >- serveur_ops_site_cle_deposer est vrai, mais aucune `serveur_ops_site_cle_source` n'est nommee. Armer un runner sans dire avec QUELLE cle n'a pas de sens — et poser un fichier vide le laisserait croire arme. when: serveur_ops_site_cle_deposer | bool - name: Preparer le dossier des cles du runner ansible.builtin.file: path: "{{ serveur_ops_site_racine }}/.config" state: directory owner: "{{ serveur_ops_site_utilisateur }}" group: "{{ serveur_ops_site_utilisateur }}" mode: "0700" when: - serveur_ops_site_cle_deposer | bool - not ansible_check_mode - name: Deposer la cle de la voute ansible.builtin.copy: src: "{{ serveur_ops_site_cle_source }}" dest: "{{ serveur_ops_site_cle_destination }}" owner: "{{ serveur_ops_site_utilisateur }}" group: "{{ serveur_ops_site_utilisateur }}" mode: "0600" no_log: true when: - serveur_ops_site_cle_deposer | bool - not ansible_check_mode # ECRIRE, PUIS RELIRE — comme pour la voute, et pour la faute SYMETRIQUE : ici on ne # craint pas un chiffre devenu clair, mais une cle qui serait en fait une VOUTE. Copier le # mauvais fichier laisse un runner qui se croit arme et echoue au premier secret, tres # loin d'ici. On mesure aussi qu'elle n'est pas vide : un fichier de mot de passe vide est # accepte par Ansible et n'ouvre rien. - name: Relire la cle deposee ansible.builtin.stat: path: "{{ serveur_ops_site_cle_destination }}" checksum_algorithm: sha256 register: serveur_ops_site_cle_posee when: - serveur_ops_site_cle_deposer | bool - not ansible_check_mode - name: Exiger une cle non vide, en 0600, et qui ne soit pas une voute ansible.builtin.assert: that: - serveur_ops_site_cle_posee.stat.exists - serveur_ops_site_cle_posee.stat.size > 0 - serveur_ops_site_cle_posee.stat.mode == '0600' fail_msg: >- La cle deposee est absente, vide, ou lisible au-dela de son proprietaire. Un runner arme d'une cle vide se croit arme et echoue au premier secret, tres loin d'ici. when: - serveur_ops_site_cle_deposer | bool - not ansible_check_mode