fix(web-app): realign the persisted database password before the health gate

matomo, moodle and nextcloud keep the database password inside a config
file on their data volume. When the deploy rotates credentials, the
container gets the new password while its persisted config still carries
the old one, and the app fails to authenticate against its own database.

Patch the persisted file before the health gate reads it. The value goes
through the environment rather than the command line, and sed_escape
guards the delimiter, backslash and ampersand that would otherwise corrupt
the file the replacement is meant to repair.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
kevinveenbirkenbachandClaude Opus 5 committed 2026-08-18 11:45:28 +02:00
1 parent 21888ef9a2
commit 3831c8f804
6 files changed
+84

No files matched your search

+3
View File
@@ -4,6 +4,9 @@
- name: "🔍 Matomo | Resolve token from store/config"
include_tasks: 01_token_store.yml
- name: "🔑 Realign the persisted database credentials before the health gate"
include_tasks: utils/patch_db_credentials.yml
- name: "🧩 load docker, db and proxy for {{ application_id }}"
include_role:
name: sys-stk-full
@@ -0,0 +1,25 @@
---
- name: "🧭 Resolve the matomo_data mountpoint, empty while the volume is absent"
ansible.builtin.shell:
cmd: >-
container volume ls -q -f name=^matomo_data$ | grep -q . &&
container volume inspect --format '{{ "{{" }}.Mountpoint{{ "}}" }}' matomo_data || true
register: matomo_data_mountpoint_pre
changed_when: false
- name: "🔎 Check whether the persisted config exists"
ansible.builtin.stat:
path: "{{ [matomo_data_mountpoint_pre.stdout | trim, 'config/config.ini.php'] | path_join }}"
register: matomo_config_stat_pre
when: (matomo_data_mountpoint_pre.stdout | trim) != ""
- name: "🔄 Update the database password in the persisted config"
ansible.builtin.shell:
cmd: >-
sed -i "s|^password *=.*|password = ${PATCH_PASSWORD}|"
{{ ([matomo_data_mountpoint_pre.stdout | trim, 'config/config.ini.php'] | path_join) | quote }}
environment:
PATCH_PASSWORD: "{{ lookup('database', application_id, 'password') | sed_escape('|') }}"
no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"
changed_when: true
when: matomo_config_stat_pre.stat.exists | default(false)
+3
View File
@@ -1,6 +1,9 @@
---
- include_tasks: utils/once/flag.yml
- name: "🔑 Realign the persisted database credentials before the health gate"
include_tasks: utils/patch_db_credentials.yml
- name: "🧩 load docker, db and proxy for {{ application_id }}"
include_role:
name: sys-stk-full
@@ -0,0 +1,25 @@
---
- name: "🧭 Resolve the moodle_code mountpoint, empty while the volume is absent"
ansible.builtin.shell:
cmd: >-
container volume ls -q -f name=^moodle_code$ | grep -q . &&
container volume inspect --format '{{ "{{" }}.Mountpoint{{ "}}" }}' moodle_code || true
register: moodle_code_mountpoint
changed_when: false
- name: "🔎 Check whether the persisted config exists"
ansible.builtin.stat:
path: "{{ [moodle_code_mountpoint.stdout | trim, 'config.php'] | path_join }}"
register: moodle_config_stat
when: (moodle_code_mountpoint.stdout | trim) != ""
- name: "🔄 Update the database password in the persisted config"
ansible.builtin.shell:
cmd: >-
sed -i "s|^\$CFG->dbpass *=.*|\$CFG->dbpass = '${PATCH_PASSWORD}';|"
{{ ([moodle_code_mountpoint.stdout | trim, 'config.php'] | path_join) | quote }}
environment:
PATCH_PASSWORD: "{{ lookup('database', application_id, 'password') | sed_escape('|') }}"
no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"
changed_when: true
when: moodle_config_stat.stat.exists | default(false)
@@ -1,6 +1,9 @@
---
- include_tasks: utils/once/flag.yml
- name: "🔑 Realign the persisted database credentials before the health gate"
include_tasks: utils/patch_db_credentials.yml
- name: 🔧 Setup the full docker stack
include_tasks: 01_fullstack.yml
vars:
@@ -0,0 +1,25 @@
---
- name: "🧭 Resolve the nextcloud_data mountpoint, empty while the volume is absent"
ansible.builtin.shell:
cmd: >-
container volume ls -q -f name=^nextcloud_data$ | grep -q . &&
container volume inspect --format '{{ "{{" }}.Mountpoint{{ "}}" }}' nextcloud_data || true
register: nextcloud_data_mountpoint
changed_when: false
- name: "🔎 Check whether the persisted config exists"
ansible.builtin.stat:
path: "{{ [nextcloud_data_mountpoint.stdout | trim, 'config/config.php'] | path_join }}"
register: nextcloud_config_stat
when: (nextcloud_data_mountpoint.stdout | trim) != ""
- name: "🔄 Update the database password in the persisted config"
ansible.builtin.shell:
cmd: >-
sed -i "s|'dbpassword' *=> *'.*'|'dbpassword' => '${PATCH_PASSWORD}'|"
{{ ([nextcloud_data_mountpoint.stdout | trim, 'config/config.php'] | path_join) | quote }}
environment:
PATCH_PASSWORD: "{{ lookup('database', application_id, 'password') | sed_escape('|') }}"
no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"
changed_when: true
when: nextcloud_config_stat.stat.exists | default(false)