--- - name: Podman CDR Link | PATCH | Install data plate ansible.builtin.template: src: etc/motd.d/10-data-plate.txt dest: /etc/motd.d/10-data-plate.txt owner: root group: root mode: "0444" become: true - name: Podman CDR Link | PATCH | Install podman and verify rootless podman user ansible.builtin.include_role: role: sr2c.core.podman_host vars: podman_host_minimum_unpriv_port: 80 podman_host_rootless_users: ["{{ podman_link_podman_rootless_user }}"] - name: Podman CDR Link | AUDIT | Get subuid range for user ansible.builtin.command: cmd: "getsubids {{ podman_link_podman_rootless_user }}" register: _podman_link_user_subuid changed_when: false - name: Podman CDR Link | AUDIT | Get subgid range for user ansible.builtin.command: cmd: "getsubids -g {{ podman_link_podman_rootless_user }}" register: _podman_link_user_subgid changed_when: false - name: Podman CDR Link | AUDIT | Parse outputs of getsubids and store results ansible.builtin.set_fact: _podman_link_user_subuid_start: "{{ (_podman_link_user_subuid.stdout_lines[0].split()[2] | int) }}" _podman_link_user_subgid_start: "{{ (_podman_link_user_subgid.stdout_lines[0].split()[2] | int) }}" - name: Podman CDR Link | PATCH | Set sysctl vm.max_map_count for Opensearch tuning ansible.posix.sysctl: name: vm.max_map_count value: '262144' state: present become: true - name: Podman CDR Link | PATCH | Set vm.overcommit_memory for Memcached tuning ansible.posix.sysctl: name: vm.overcommit_memory value: '1' state: present become: true # Opensearch runs with UID/GID 1000 inside the container - name: Podman CDR Link | PATCH | Create data directory for Opensearch ansible.builtin.file: path: "/home/{{ podman_link_podman_rootless_user }}/opensearch-data" owner: "{{ _podman_link_user_subuid_start + 999 }}" group: "{{ _podman_link_user_subgid_start + 999 }}" mode: "0700" state: "directory" become: true # Opensearch runs with UID/GID 1000 inside the container - name: Podman CDR Link | PATCH | Install Opensearch configuration ansible.builtin.copy: src: home/opensearch-config.yml dest: "/home/{{ podman_link_podman_rootless_user }}/opensearch-config.yml" mode: "0400" owner: "{{ _podman_link_user_subuid_start + 999 }}" group: "{{ _podman_link_user_subgid_start + 999 }}" become: true notify: - Restart Link # Zammad runs with UID/GID 1000 inside the container - name: Podman CDR Link | PATCH | Install Zammad database configuration file ansible.builtin.template: src: home/zammad-database.yml dest: "/home/{{ podman_link_podman_rootless_user }}/zammad-database.yml" owner: "{{ _podman_link_user_subuid_start + 999 }}" group: "{{ _podman_link_user_subuid_start + 999 }}" mode: "0400" become: true notify: - Restart Link # Zammad runs with UID/GID 1000 inside the container - name: Podman CDR Link | PATCH | Create data directories for Zammad ansible.builtin.file: path: "/home/{{ podman_link_podman_rootless_user }}/{{ item }}" owner: "{{ _podman_link_user_subuid_start + 999 }}" group: "{{ _podman_link_user_subgid_start + 999 }}" mode: "0700" state: "directory" become: true with_items: - zammad-storage - zammad-var - zammad-backup - zammad-data - zammad-config-nginx # Bridge/Link runs with UID/GID 1000 inside the container (because it's based on the node container) - name: Podman CDR Link | PATCH | Create data directory for bridge-whatsapp ansible.builtin.file: path: "/home/{{ podman_link_podman_rootless_user }}/bridge-whatsapp-data" owner: "{{ _podman_link_user_subuid_start + 999 }}" group: "{{ _podman_link_user_subgid_start + 999 }}" mode: "0700" state: "directory" become: true # Postgres/Redis runs with UID/GID 999 inside the container # Postgres seems to want to set group permissions on the data directory, which is probably fine - name: Podman CDR Link | PATCH | Create data directory for PostgreSQL and Redis ansible.builtin.file: path: "/home/{{ podman_link_podman_rootless_user }}/{{ item }}" owner: "{{ _podman_link_user_subuid_start + 998 }}" group: "{{ _podman_link_user_subgid_start + 998 }}" mode: "0750" state: "directory" become: true with_items: - bridge-postgresql-data - redis-data - postgresql-data # We set the UID/GID to 1002 inside the signal-cli-rest-api container with environment variables - name: Podman CDR Link | PATCH | Create data directory for signal-cli-rest-api ansible.builtin.file: path: "/home/{{ podman_link_podman_rootless_user }}/signal-cli-rest-api-data" owner: "{{ _podman_link_user_subuid_start + 1001 }}" group: "{{ _podman_link_user_subgid_start + 1001 }}" mode: "0700" state: "directory" become: true - name: Podman CDR Link | PATCH | Install shared environment files ansible.builtin.template: src: "home/config/containers/systemd/{{ item }}" dest: "/home/{{ podman_link_podman_rootless_user }}/.config/containers/systemd/{{ item }}" owner: "{{ podman_link_podman_rootless_user }}" mode: "0400" become: true with_items: - common-zammad.env - common-bridge.env notify: - Restart Link - name: Podman CDR Link | PATCH | Install container quadlets ansible.builtin.template: src: "home/config/containers/systemd/{{ item }}" dest: "/home/{{ podman_link_podman_rootless_user }}/.config/containers/systemd/{{ item }}" owner: "{{ podman_link_podman_rootless_user }}" mode: "0400" with_items: - link.container - zammad-opensearch.container - opensearch-dashboards.container - bridge-worker.container - bridge-postgresql.container - bridge-whatsapp.container - signal-cli-rest-api.container - zammad-init.container - zammad-nginx.container - zammad-railsserver.container - zammad-scheduler.container - zammad-postgresql.container - zammad-websocket.container - zammad-redis.container - zammad-memcached.container become: true notify: - Restart Link - name: Podman CDR Link | PATCH | Install network quadlets ansible.builtin.template: src: "home/config/containers/systemd/{{ item }}" dest: "/home/{{ podman_link_podman_rootless_user }}/.config/containers/systemd/{{ item }}" owner: "{{ podman_link_podman_rootless_user }}" mode: "0400" with_items: - frontend.network - link.network become: true notify: - Restart Link - name: Podman CDR Link | AUDIT | Verify quadlets are correctly defined ansible.builtin.command: /usr/libexec/podman/quadlet -dryrun -user register: podman_link_quadlet_result ignore_errors: true changed_when: false become: true become_user: "{{ podman_link_podman_rootless_user }}" - name: Podman CDR Link | AUDIT | Assert that the quadlet verification succeeded ansible.builtin.assert: that: - podman_link_quadlet_result.rc == 0 fail_msg: "'/usr/libexec/podman/quadlet -dryrun -user' failed! Output withheld to prevent leaking secrets." - name: Podman CDR Link | PATCH | Set up nginx and Let's Encrypt certificate ansible.builtin.include_role: name: sr2c.core.podman_nginx vars: podman_nginx_frontend_network: frontend podman_nginx_podman_rootless_user: "{{ podman_link_podman_rootless_user }}" podman_nginx_primary_hostname: "{{ podman_link_web_hostname }}" podman_nginx_systemd_service_slice: "link.slice" - name: Podman CDR Link | PATCH | Install production nginx configuration file ansible.builtin.template: src: home/nginx.conf dest: "/home/{{ podman_link_podman_rootless_user }}/nginx/nginx.conf" owner: "{{ podman_link_podman_rootless_user }}" group: "{{ podman_link_podman_rootless_user }}" mode: "0644" become: true notify: - Restart nginx - name: Podman CDR Link | PATCH | Install additional systemd units (services, targets, and slice) ansible.builtin.template: src: "home/config/systemd/user/{{ item }}" dest: "/home/{{ podman_link_podman_rootless_user }}/.config/systemd/user/{{ item }}" owner: "{{ podman_link_podman_rootless_user }}" group: "{{ podman_link_podman_rootless_user }}" mode: "0400" become: true with_items: - "zammad-reindex.service" - "link.slice" - "link.target" - "zammad-storage.target" notify: - Restart Link - name: Podman CDR Link | PATCH | Ensure zammad-opensearch is running ansible.builtin.systemd_service: name: zammad-opensearch.service state: started scope: user daemon_reload: true become: true become_user: "{{ podman_link_podman_rootless_user }}" - name: Podman CDR Link | AUDIT | Check if Opensearch setup script has been run ansible.builtin.stat: path: "/home/{{ podman_link_podman_rootless_user }}/.securityadmin_done" become: true register: _podman_link_opensearch_securityadmin_done - name: Podman CDR Link | PATCH | Ensure Opensearch setup script is executable containers.podman.podman_container_exec: name: zammad-opensearch command: chmod +x /usr/share/opensearch/plugins/opensearch-security/tools/securityadmin.sh become: true become_user: "{{ podman_link_podman_rootless_user }}" when: not _podman_link_opensearch_securityadmin_done.stat.exists - name: Podman CDR Link | PATCH | Run Opensearch setup script containers.podman.podman_container_exec: name: zammad-opensearch argv: - /usr/share/opensearch/plugins/opensearch-security/tools/securityadmin.sh - -cd - /usr/share/opensearch/config/opensearch-security/ - -icl - -key - /usr/share/opensearch/config/kirk-key.pem - -cert - /usr/share/opensearch/config/kirk.pem - -cacert - /usr/share/opensearch/config/root-ca.pem - -nhnv become: true become_user: "{{ podman_link_podman_rootless_user }}" register: _podman_link_opensearch_securityadmin_result retries: 20 delay: 5 until: _podman_link_opensearch_securityadmin_result.rc == 0 when: not _podman_link_opensearch_securityadmin_done.stat.exists - name: Podman CDR Link | PATCH | Mark Opensearch setup script as having run ansible.builtin.file: path: "/home/{{ podman_link_podman_rootless_user }}/.securityadmin_done" state: touch owner: "{{ podman_link_podman_rootless_user }}" group: "{{ podman_link_podman_rootless_user }}" mode: "0000" modification_time: preserve access_time: preserve become: true - name: Podman CDR Link | PATCH | Ensure zammad-railsserver is running ansible.builtin.systemd_service: name: zammad-railsserver.service state: started scope: user become: true become_user: "{{ podman_link_podman_rootless_user }}" - name: Podman CDR Link | AUDIT | Wait for zammad-init to finish containers.podman.podman_container_exec: name: zammad-railsserver argv: - bundle - exec - rails - r - 'ActiveRecord::Migration.check_all_pending!; Translation.any? || raise' register: _podman_link_zammad_init_wait until: _podman_link_zammad_init_wait.rc == 0 retries: 30 delay: 5 become: true become_user: "{{ podman_link_podman_rootless_user }}" changed_when: false - name: Podman CDR Link | AUDIT | Check if Zammad wants to verify SSL connections to Opensearch containers.podman.podman_container_exec: name: zammad-railsserver argv: - rails - r - "print Setting.get('es_ssl_verify')" become: true become_user: "{{ podman_link_podman_rootless_user }}" register: _podman_link_zammad_es_ssl_verify changed_when: false - name: Podman CDR Link | PATCH | Configure Zammad to not verify SSL connections to Opensearch containers.podman.podman_container_exec: name: zammad-railsserver argv: - rails - r - "Setting.set('es_ssl_verify', false)" become: true become_user: "{{ podman_link_podman_rootless_user }}" when: (_podman_link_zammad_es_ssl_verify.stdout | trim)[-5:] != "false" - name: Podman CDR Link | PATCH | Make sure all services are running now and started on boot ansible.builtin.systemd_service: name: "link.target" enabled: true state: started masked: false daemon_reload: true scope: user become: true become_user: "{{ podman_link_podman_rootless_user }}"