ajoute le stockage S3 des devoirs maison (bloc B, dernier chantier)

Dépôt de fichier en plus du texte libre pour les devoirs maison, stocké
sur Hetzner Object Storage (jamais sur le disque du serveur), masqué
côté élève tant que le bucket n'est pas configuré. Purge RGPD étendue
pour supprimer aussi les fichiers d'Object Storage. Ansible lit les
identifiants depuis un fichier que seul Adam peut créer sur le serveur
(runbook docs/runbooks/stockage-s3.md) ; le bloc B du CLAUDE.md est
maintenant complet.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Adam Belkacemi 2026-10-14 09:52:15 +02:00
parent 79d4a06fdf
commit 6ea7a1cc16
16 changed files with 1022 additions and 59 deletions

View file

@ -144,6 +144,50 @@
# redémarrage, il garderait l'ancien mot de passe après une rotation.
notify: redémarrer horizon
# Bloc B, stockage S3 (2026-10-14) : fichier créé à la main par Adam sur le
# serveur, jamais par Ansible ni par Claude (CLAUDE.md, commandes et
# dépenses). Tant qu'il n'existe pas, ce bloc ne touche à rien : le dépôt de
# fichier des devoirs reste simplement masqué côté portail
# (StockageTravauxEleves::disponible()) — voir docs/runbooks/stockage-s3.md.
- name: vérifier si les identifiants S3 existent (étape 10, facultatif)
ansible.builtin.stat:
path: /etc/syllabus/s3-paillasse.yaml
register: portail_s3_stat
- name: lire les identifiants S3 du portail (étape 10)
ansible.builtin.slurp:
src: /etc/syllabus/s3-paillasse.yaml
register: portail_s3_brut
when: portail_s3_stat.stat.exists
- name: extraire les champs S3
ansible.builtin.set_fact:
portail_s3_access_key: "{{ portail_s3_contenu | regex_search('access_key:\\s*\"?([^\"\\n]+)', '\\1') | first }}"
portail_s3_secret_key: "{{ portail_s3_contenu | regex_search('secret_key:\\s*\"?([^\"\\n]+)', '\\1') | first }}"
portail_s3_bucket: "{{ portail_s3_contenu | regex_search('bucket:\\s*\"?([^\"\\n]+)', '\\1') | first }}"
portail_s3_region: "{{ portail_s3_contenu | regex_search('region:\\s*\"?([^\"\\n]+)', '\\1') | first }}"
portail_s3_endpoint: "{{ portail_s3_contenu | regex_search('endpoint:\\s*\"?([^\"\\n]+)', '\\1') | first }}"
vars:
portail_s3_contenu: "{{ portail_s3_brut.content | b64decode }}"
when: portail_s3_stat.stat.exists
no_log: true
- name: ajouter/mettre à jour les variables S3 dans .env
ansible.builtin.lineinfile:
path: "{{ portail_dossier_app }}/.env"
regexp: "^{{ item.cle }}="
line: "{{ item.cle }}={{ item.valeur }}"
loop:
- { cle: "AWS_ACCESS_KEY_ID", valeur: "{{ portail_s3_access_key }}" }
- { cle: "AWS_SECRET_ACCESS_KEY", valeur: "{{ portail_s3_secret_key }}" }
- { cle: "AWS_BUCKET", valeur: "{{ portail_s3_bucket }}" }
- { cle: "AWS_DEFAULT_REGION", valeur: "{{ portail_s3_region }}" }
- { cle: "AWS_ENDPOINT", valeur: "{{ portail_s3_endpoint }}" }
- { cle: "AWS_USE_PATH_STYLE_ENDPOINT", valeur: "false" }
when: portail_s3_stat.stat.exists
no_log: true
notify: redémarrer horizon
- name: installer les dépendances JS (npm)
ansible.builtin.command:
cmd: npm ci