mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-06 19:01:54 +00:00
At -vvv Ansible prints each module argument and result, so a password in a command line, a request body, a header or a fact lands in the deploy log. Nothing enforced masking outside the MCP task files, and no check looked at parents at all. A new lint, test_credential_tasks_are_masked, finds tasks whose printed parts (module arguments, environment, loop) reference an identifier ending in password, secret, token, api_key or private_key, or secrets.credentials. A task passes when it or an enclosing block sets no_log, when every file that pulls it in does so through include_tasks with apply.no_log or import_tasks with no_log (transitively), when the secret only reaches a parameter the module masks itself, or when the module masks its values. no_log on an include_tasks task itself does not count, because it does not reach the included tasks. The rule can be suppressed per task with `# nocheck: credential-masking`, now listed in the suppression catalog, and the lint tests its parent and suppression logic on synthetic cases. It found 39 unmasked tasks in 19 roles, all real: join tokens, client secrets, API tokens in Cloudflare headers, database passwords in command lines, the ChatGPT bot login body and more. Each now sets no_log from MASK_CREDENTIALS_IN_LOGS. The sys-dns-hetzner-rdns alias hetzner_no_log, which only restated that switch, is gone. Not covered yet: template and copy tasks whose rendered file carries a secret print it as a diff under --diff. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
76 lines
3.9 KiB
YAML
76 lines
3.9 KiB
YAML
---
|
||
- name: "🔍 Resolve mattermost hosting node + container id"
|
||
ansible.builtin.include_tasks: "{{ lookup('path_absolute', 'roles/sys-svc-compose/tasks/utils/swarm/resolve_host_cid.yml') }}"
|
||
vars:
|
||
resolve_service_key: "{{ entity_name }}"
|
||
resolve_output_prefix: MATTERMOST
|
||
resolve_compose_cid: "{{ MATTERMOST_CONTAINER_ADDRESS }}"
|
||
resolve_converge_retries: 120
|
||
resolve_converge_delay: 5
|
||
|
||
- name: "⏳ Mattermost | Wait until mmctl local mode is ready"
|
||
ansible.builtin.shell: | # nocheck: container-exec-resolver MATTERMOST_LOCAL_CID resolved at delegate_to runtime; container_address would return a manager-only subshell
|
||
container exec -i {{ MATTERMOST_LOCAL_CID | quote }} \
|
||
/mattermost/bin/mmctl --local system status
|
||
register: mm_ready_wait
|
||
retries: 60
|
||
delay: 5
|
||
until: mm_ready_wait.rc == 0
|
||
changed_when: false
|
||
failed_when: mm_ready_wait.rc != 0 and mm_ready_wait.attempts == 61
|
||
delegate_to: "{{ MATTERMOST_HOST_NODE }}"
|
||
|
||
- name: "📁 Mattermost | Create system administrator user"
|
||
no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"
|
||
ansible.builtin.shell: | # nocheck: container-exec-resolver MATTERMOST_LOCAL_CID resolved at delegate_to runtime; container_address would return a manager-only subshell
|
||
container exec -i {{ MATTERMOST_LOCAL_CID | quote }} \
|
||
/mattermost/bin/mmctl --local user create \
|
||
--email "{{ lookup('users', 'administrator').email }}" \
|
||
--username "{{ lookup('users', 'administrator').username }}" \
|
||
--password {{ lookup('users', 'administrator').password | quote }} \
|
||
--system-admin
|
||
register: mm_create_admin
|
||
changed_when: mm_create_admin.rc == 0
|
||
failed_when: mm_create_admin.rc != 0 and 'already exists' not in (mm_create_admin.stdout + mm_create_admin.stderr)
|
||
delegate_to: "{{ MATTERMOST_HOST_NODE }}"
|
||
|
||
- name: "📁 Mattermost | Create default team"
|
||
ansible.builtin.shell: | # nocheck: container-exec-resolver MATTERMOST_LOCAL_CID resolved at delegate_to runtime; container_address would return a manager-only subshell
|
||
container exec -i {{ MATTERMOST_LOCAL_CID | quote }} \
|
||
/mattermost/bin/mmctl --local team create \
|
||
--name "main" \
|
||
--display-name "{{ ORGANIZATION }}"
|
||
register: mm_create_team
|
||
changed_when: mm_create_team.rc == 0
|
||
failed_when: mm_create_team.rc != 0 and 'already exists' not in (mm_create_team.stdout + mm_create_team.stderr) and 'existing team' not in
|
||
(mm_create_team.stdout + mm_create_team.stderr)
|
||
delegate_to: "{{ MATTERMOST_HOST_NODE }}"
|
||
|
||
- name: "🟢 Mattermost | Enable open invite on default team"
|
||
database_query:
|
||
config: "{{ lookup('database', application_id) }}"
|
||
query_file: "{{ role_path }}/files/sql/update/default-team-open-invite.sql"
|
||
mask_values: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"
|
||
changed_when: false
|
||
|
||
- name: "🔎 Mattermost | Check which users are already in default team"
|
||
ansible.builtin.shell: | # nocheck: container-exec-resolver MATTERMOST_LOCAL_CID resolved at delegate_to runtime; container_address would return a manager-only subshell
|
||
container exec -i {{ MATTERMOST_LOCAL_CID | quote }} \
|
||
/mattermost/bin/mmctl --local user list --team main
|
||
register: mm_team_members
|
||
changed_when: false
|
||
delegate_to: "{{ MATTERMOST_HOST_NODE }}"
|
||
|
||
- name: "➕ Mattermost | Add administrator to default team"
|
||
ansible.builtin.shell: | # nocheck: container-exec-resolver MATTERMOST_LOCAL_CID resolved at delegate_to runtime; container_address would return a manager-only subshell
|
||
container exec -i {{ MATTERMOST_LOCAL_CID | quote }} \
|
||
/mattermost/bin/mmctl --local team users add \
|
||
main \
|
||
"{{ lookup('users', 'administrator').email }}"
|
||
when: lookup('users', 'administrator').email not in mm_team_members.stdout
|
||
delegate_to: "{{ MATTERMOST_HOST_NODE }}"
|
||
|
||
- name: "🗂️ Mattermost | Wire administrator OIDC auth"
|
||
ansible.builtin.include_tasks: 03_oidc_admin.yml
|
||
when: MATTERMOST_OIDC_ENABLED | bool
|