114 lines
4.7 KiB
YAML
114 lines
4.7 KiB
YAML
|
|
---
|
||
|
|
- name: Exiger les intrants du runner de tenant
|
||
|
|
ansible.builtin.assert:
|
||
|
|
that:
|
||
|
|
- serveur_ops_tenant_depot | length > 0
|
||
|
|
- (not (serveur_ops_tenant_voute_deposer | bool))
|
||
|
|
or (serveur_ops_tenant_voute_source | length > 0)
|
||
|
|
fail_msg: >-
|
||
|
|
serveur_ops_tenant exige `serveur_ops_tenant_depot` (le dossier de CET écosystème
|
||
|
|
chez le runner, cloné par serveur_ops — il vaut `serveur_ops_instance` par défaut)
|
||
|
|
et, si le dépôt de la voûte est demandé, `serveur_ops_tenant_voute_source`
|
||
|
|
(le chemin de son `vault.yml` sur le contrôleur).
|
||
|
|
|
||
|
|
- name: Le plan de l'écosystème est-il bien là ?
|
||
|
|
ansible.builtin.stat:
|
||
|
|
path: "{{ serveur_ops_tenant_racine }}/{{ serveur_ops_tenant_depot }}/plan/serveurs.yml"
|
||
|
|
register: serveur_ops_tenant_plan
|
||
|
|
|
||
|
|
- name: Refuser si le plan de l'écosystème manque
|
||
|
|
ansible.builtin.assert:
|
||
|
|
that:
|
||
|
|
- serveur_ops_tenant_plan.stat.exists
|
||
|
|
fail_msg: >-
|
||
|
|
{{ serveur_ops_tenant_racine }}/{{ serveur_ops_tenant_depot }}/plan/serveurs.yml est
|
||
|
|
absent. Déclarer ce dépôt dans `serveur_ops_depots` (role: instance) et rejouer
|
||
|
|
serveur_ops : donner sa voûte à un runner qui n'a pas le plan qu'elle ouvre ne
|
||
|
|
configure rien — ça ne fait que déposer un secret.
|
||
|
|
when: not ansible_check_mode
|
||
|
|
|
||
|
|
# LE DOSSIER D'INVENTAIRE SE DÉCOUVRE. Deux noms existent dans le dépôt (`principal`,
|
||
|
|
# `production`) et l'écrire en dur le ferait mentir pour l'écosystème qui emploie l'autre.
|
||
|
|
- name: Chercher le dossier d'inventaire de cet écosystème
|
||
|
|
ansible.builtin.stat:
|
||
|
|
path: "{{ serveur_ops_tenant_racine }}/{{ serveur_ops_tenant_depot }}/inventories/{{ item }}"
|
||
|
|
register: serveur_ops_tenant_candidats
|
||
|
|
loop: "{{ serveur_ops_tenant_inventaires_connus }}"
|
||
|
|
loop_control:
|
||
|
|
label: "{{ item }}"
|
||
|
|
|
||
|
|
- name: Retenir le premier qui existe
|
||
|
|
ansible.builtin.set_fact:
|
||
|
|
serveur_ops_tenant_inventaire: >-
|
||
|
|
{{ (serveur_ops_tenant_candidats.results | selectattr('stat.exists')
|
||
|
|
| map(attribute='item') | list | first) | default('') }}
|
||
|
|
|
||
|
|
- name: Refuser si aucun inventaire n'est reconnu
|
||
|
|
ansible.builtin.assert:
|
||
|
|
that:
|
||
|
|
- serveur_ops_tenant_inventaire | length > 0
|
||
|
|
fail_msg: >-
|
||
|
|
Aucun dossier d'inventaire trouvé sous
|
||
|
|
{{ serveur_ops_tenant_racine }}/{{ serveur_ops_tenant_depot }}/inventories/ parmi
|
||
|
|
{{ serveur_ops_tenant_inventaires_connus | join(', ') }}. Sans lui, on ne saurait pas
|
||
|
|
où déposer la voûte — et la déposer au mauvais endroit revient à ne pas la déposer,
|
||
|
|
en laissant croire le contraire.
|
||
|
|
when: not ansible_check_mode
|
||
|
|
|
||
|
|
- name: Préparer le dossier des variables communes
|
||
|
|
ansible.builtin.file:
|
||
|
|
path: >-
|
||
|
|
{{ serveur_ops_tenant_racine }}/{{ serveur_ops_tenant_depot }}/inventories/{{
|
||
|
|
serveur_ops_tenant_inventaire }}/group_vars/all
|
||
|
|
state: directory
|
||
|
|
owner: "{{ serveur_ops_tenant_utilisateur }}"
|
||
|
|
group: "{{ serveur_ops_tenant_utilisateur }}"
|
||
|
|
mode: "0700"
|
||
|
|
when:
|
||
|
|
- serveur_ops_tenant_voute_deposer | bool
|
||
|
|
- not ansible_check_mode
|
||
|
|
|
||
|
|
# LES SECRETS DE L'ÉCOSYSTÈME, DE DROIT ET NON PAR EMPRUNT.
|
||
|
|
#
|
||
|
|
# `decrypt: false` : 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 de l'écosystème (chiffrée)
|
||
|
|
ansible.builtin.copy:
|
||
|
|
src: "{{ serveur_ops_tenant_voute_source }}"
|
||
|
|
dest: >-
|
||
|
|
{{ serveur_ops_tenant_racine }}/{{ serveur_ops_tenant_depot }}/inventories/{{
|
||
|
|
serveur_ops_tenant_inventaire }}/group_vars/all/vault.yml
|
||
|
|
owner: "{{ serveur_ops_tenant_utilisateur }}"
|
||
|
|
group: "{{ serveur_ops_tenant_utilisateur }}"
|
||
|
|
mode: "0600"
|
||
|
|
decrypt: false
|
||
|
|
when:
|
||
|
|
- serveur_ops_tenant_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 secrets de l'écosystème dorment en
|
||
|
|
# clair sur une machine.
|
||
|
|
- name: Relire l'en-tête de la voûte déposée
|
||
|
|
ansible.builtin.command:
|
||
|
|
cmd: >-
|
||
|
|
head -c 21 {{ serveur_ops_tenant_racine }}/{{ serveur_ops_tenant_depot
|
||
|
|
}}/inventories/{{ serveur_ops_tenant_inventaire }}/group_vars/all/vault.yml
|
||
|
|
register: serveur_ops_tenant_entete
|
||
|
|
changed_when: false
|
||
|
|
when:
|
||
|
|
- serveur_ops_tenant_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_tenant_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 secrets de cet écosystème comme exposés.
|
||
|
|
when:
|
||
|
|
- serveur_ops_tenant_voute_deposer | bool
|
||
|
|
- not ansible_check_mode
|