ajoute la liaison Laravel-OpenStack et le modèle Heat du lab 08

Un gabarit Heat généré depuis chaque lab.yaml, une stack par session de
lab (création à l'admission, suppression à l'expiration via des jobs
Redis et un worker systemd dédié). Passage du compte de service à une
authentification par mot de passe : Heat refuse de créer un trust à
partir d'un jeton d'application credential (voir ADR 0002).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Adam Belkacemi 2026-10-08 10:14:24 +02:00
parent 8742bde807
commit 67a754f733
34 changed files with 1095 additions and 91 deletions

View file

@ -44,6 +44,7 @@
- "--exclude=/public/hot"
- "--exclude=/.git"
register: portail_code_synchronise
notify: redémarrer le worker de file
- name: installer les dépendances PHP (composer)
ansible.builtin.command:
@ -81,18 +82,24 @@
portail_app_url: "http://{{ ansible_host }}"
when: not portail_env_stat.stat.exists
# Variables ajoutées après le premier déploiement (étape 9) : mises à jour
# ligne par ligne, pour ne jamais retoucher le reste d'un .env déjà en place
# (APP_KEY en particulier, qui ne doit jamais changer sans le vouloir).
- name: lire l'application credential OpenStack du portail (étape 6)
# Variables ajoutées après le premier déploiement (étapes 9 et 10) : mises à
# jour ligne par ligne, pour ne jamais retoucher le reste d'un .env déjà en
# place (APP_KEY en particulier, qui ne doit jamais changer sans le vouloir).
#
# Authentification par mot de passe, pas par application credential : Heat
# refuse de créer un trust Keystone à partir d'un jeton d'application
# credential (« Delegated tokens cannot manage trusts », constaté le
# 2026-10-08) — voir portail/config/openstack.php et docs/journal.md.
- name: lire les identifiants OpenStack du portail (étape 6)
ansible.builtin.slurp:
src: /etc/kolla/clouds-paillasse.yaml
register: portail_clouds_brut
- name: extraire l'id et le secret de l'application credential
- name: extraire le nom d'utilisateur et le mot de passe
ansible.builtin.set_fact:
portail_os_application_credential_id: "{{ portail_clouds_contenu | regex_search('application_credential_id:\\s*\"?([^\"\\n]+)', '\\1') | first }}"
portail_os_application_credential_secret: "{{ portail_clouds_contenu | regex_search('application_credential_secret:\\s*\"?([^\"\\n]+)', '\\1') | first }}"
portail_os_username: "{{ portail_clouds_contenu | regex_search('username:\\s*\"?([^\"\\n]+)', '\\1') | first }}"
portail_os_password: "{{ portail_clouds_contenu | regex_search('password:\\s*\"?([^\"\\n]+)', '\\1') | first }}"
portail_os_project_name: "{{ portail_clouds_contenu | regex_search('project_name:\\s*\"?([^\"\\n]+)', '\\1') | first }}"
vars:
portail_clouds_contenu: "{{ portail_clouds_brut.content | b64decode }}"
no_log: true
@ -105,9 +112,14 @@
loop:
- { cle: "OS_AUTH_URL", valeur: "http://10.10.0.1:5000" }
- { cle: "OS_NOVA_URL", valeur: "http://10.10.0.1:8774/v2.1" }
- { cle: "OS_APPLICATION_CREDENTIAL_ID", valeur: "{{ portail_os_application_credential_id }}" }
- { cle: "OS_APPLICATION_CREDENTIAL_SECRET", valeur: "{{ portail_os_application_credential_secret }}" }
- { cle: "OS_HEAT_URL", valeur: "http://10.10.0.1:8004/v1" }
- { cle: "OS_USERNAME", valeur: "{{ portail_os_username }}" }
- { cle: "OS_PASSWORD", valeur: "{{ portail_os_password }}" }
- { cle: "OS_PROJECT_NAME", valeur: "{{ portail_os_project_name }}" }
- { cle: "OS_APPLICATION_CREDENTIAL_ID", valeur: "" }
- { cle: "OS_APPLICATION_CREDENTIAL_SECRET", valeur: "" }
- { cle: "REDIS_PREFIX", valeur: "" }
- { cle: "LABS_DOSSIER", valeur: "/opt/labs" }
no_log: true
register: portail_env_mis_a_jour