--- # REQUIRED: # sys_token_store_user_key # sys_token_store_app # sys_token_store_token # must be non-empty - name: "✅ Ensure store exists" ansible.builtin.import_tasks: 00_core.yml - name: "📐 Normalize incoming token" ansible.builtin.set_fact: sys_token_store_token_effective: "{{ sys_token_store_token | string | trim }}" no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" - name: "🛑 Abort if token is empty (do not persist empties)" ansible.builtin.assert: that: - sys_token_store_token_effective != '' fail_msg: "sys_token_store_token is empty – refusing to persist empty token." - name: "🔨 Build merged structure" ansible.builtin.set_fact: sys_token_store_users_merged: >- {{ sys_token_store_users | combine({ sys_token_store_user_key: ( sys_token_store_users.get(sys_token_store_user_key, {}) | combine({ 'tokens': ( sys_token_store_users.get(sys_token_store_user_key, {}).get('tokens', {}) | combine({ sys_token_store_app: sys_token_store_token_effective }) ) }, recursive=True ) ) }, recursive=True ) }} no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" - name: "💾 Persist store (idempotent, single-writer via STACK_HOST)" ansible.builtin.copy: dest: "{{ FILE_TOKENS }}" owner: "{{ SYS_TOKEN_STORE_OWNER }}" group: "{{ SYS_TOKEN_STORE_GROUP }}" mode: "{{ SYS_TOKEN_STORE_FILE_MODE }}" content: "{{ {'users': sys_token_store_users_merged} | to_nice_yaml(indent=2, width=9999) }}" when: sys_token_store_users_merged != sys_token_store_users delegate_to: "{{ STACK_HOST }}" run_once: true no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" become: true register: sys_token_store_persisted - name: "🪞 Mirror the store onto the controller, where every users lookup reads" ansible.builtin.copy: dest: "{{ FILE_TOKENS }}" mode: "{{ SYS_TOKEN_STORE_FILE_MODE }}" content: "{{ {'users': sys_token_store_users_merged} | to_nice_yaml(indent=2, width=9999) }}" when: - sys_token_store_users_merged != sys_token_store_users - DEPLOYMENT_MODE == 'swarm' delegate_to: localhost run_once: true no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" register: sys_token_store_mirrored - name: 🧊 Re-render the applications SPOT the new token invalidated applications_carrier: {} when: sys_token_store_persisted is changed or sys_token_store_mirrored is changed