--- - name: Require supported server firewall backend tags: [services, packages] ansible.builtin.assert: that: - server_firewall_backend == 'firewalld' fail_msg: >- server_firewall_backend must be firewalld for the Rocky server profile. - name: Configure DuckDNS updater tags: [dotfiles, dotfiles:server, duckdns] ansible.builtin.import_tasks: duckdns.yml - name: Ensure server directories exist tags: [dotfiles, services] ansible.builtin.file: path: "{{ item.path }}" state: directory owner: "{{ item.owner }}" group: "{{ item.group }}" mode: "{{ item.mode }}" loop: "{{ server_directories | default([]) }}" loop_control: label: "{{ item.path }}" when: - item.path != '/opt/gitea/data' or not server_gitea_on_atlas | bool - item.path != server_container_stack_dir or not server_legacy_stack_retired | bool - name: Copy server dotfiles tags: [dotfiles, dotfiles:server] ansible.builtin.copy: src: "{{ playbook_dir }}/../dotfiles/server/{{ item.src }}" dest: "{{ server_user_home }}/{{ item.dest }}" owner: "{{ server_username }}" group: "{{ server_user_group }}" mode: "{{ item.mode }}" loop: "{{ server_dotfiles | default([]) }}" loop_control: label: "{{ item.dest }}" - name: Render server templates tags: [dotfiles, dotfiles:server, gitea_cutover] ansible.builtin.template: src: "{{ item.src }}" dest: "{{ item.dest if item.dest.startswith('/') else server_user_home ~ '/' ~ item.dest }}" owner: "{{ item.owner | default(server_username) }}" group: "{{ item.group | default(server_user_group) }}" mode: "{{ item.mode }}" loop: "{{ server_templates | default([]) }}" loop_control: label: "{{ item.dest }}" no_log: "{{ item.no_log | default(false) }}" when: item.src != 'server/docker-compose.yml.j2' or not server_legacy_stack_retired | bool - name: Manage Podman Compose stack tags: [services, podman] ansible.builtin.include_tasks: podman-compose.yml when: not server_legacy_stack_retired | bool - name: Import staged NPM Quadlet tasks ansible.builtin.import_tasks: npm_quadlet.yml - name: Import explicit legacy server image cleanup ansible.builtin.import_tasks: legacy_image_cleanup.yml tags: [never, server_image_cleanup] when: server_legacy_image_cleanup | default(false) | bool - name: Import Prometheus backup export identity tasks ansible.builtin.import_tasks: backup_export_identity.yml - name: Import Prometheus backup export job tasks ansible.builtin.import_tasks: backup_export_job.yml tags: [server_legacy_cleanup] - name: Import explicitly approved legacy server data cleanup ansible.builtin.import_tasks: legacy_cleanup.yml tags: [never, server_legacy_cleanup] when: server_legacy_cleanup | bool - name: Import explicit Prometheus Gitea final-export tasks ansible.builtin.import_tasks: gitea_final_export.yml - name: Import Prometheus Gitea SSH proxy tasks ansible.builtin.import_tasks: gitea_ssh_proxy.yml - name: Import Prometheus Gitea NPM proxy override tasks ansible.builtin.import_tasks: gitea_npm_proxy.yml - name: Ensure server SSH authorized key fragments directory exists tags: [services, ssh] ansible.builtin.file: path: "{{ server_ssh_authorized_key_directory }}" state: directory owner: "{{ server_username }}" group: "{{ server_user_group }}" mode: "0700" when: server_ssh_authorized_keys | length > 0 - name: Manage server SSH authorized key fragments tags: [services, ssh] ansible.builtin.copy: content: "{{ item.key }}\n" dest: "{{ server_ssh_authorized_key_directory }}/{{ item.name }}" owner: "{{ server_username }}" group: "{{ server_user_group }}" mode: "0600" loop: "{{ server_ssh_authorized_keys }}" loop_control: label: "{{ item.name }}" when: server_ssh_authorized_keys | length > 0 - name: Configure server SSH authorized key fragments tags: [services, ssh, prometheus_backup] ansible.builtin.lineinfile: path: /etc/ssh/sshd_config regexp: '^\s*AuthorizedKeysFile\s+' line: >- AuthorizedKeysFile {{ ((server_ssh_authorized_keys | map(attribute='name') | map('regex_replace', '^', '%h/.ssh/authorized_keys.d/') | list) + (['%h/.ssh/authorized_keys.d/' ~ server_backup_public_key_name] if server_backup_export_enabled | bool else [])) | join(' ') }} state: present validate: "sshd -t -f %s" notify: Reload SSH service when: server_ssh_authorized_keys | length > 0 - name: Disable SSH root login on server tags: [services] ansible.builtin.lineinfile: path: /etc/ssh/sshd_config regexp: '^\s*PermitRootLogin\s+' line: "PermitRootLogin {{ server_sshd_settings.PermitRootLogin }}" state: present validate: "sshd -t -f %s" notify: Reload SSH service - name: Restrict SSH login to allowed users on server tags: [services, prometheus_backup] ansible.builtin.lineinfile: path: /etc/ssh/sshd_config regexp: '^\s*AllowUsers\s+' line: >- AllowUsers {{ (server_sshd_allow_users + ([server_backup_username] if server_backup_export_enabled | bool else [])) | join(' ') }} state: present validate: "sshd -t -f %s" notify: Reload SSH service when: (server_sshd_allow_users | default([])) | length > 0 - name: Allow server services through firewalld tags: [services, packages] ansible.posix.firewalld: service: "{{ item }}" zone: "{{ server_firewalld_zone }}" state: enabled permanent: true immediate: true loop: "{{ server_firewalld_services | default([]) }}" loop_control: label: "{{ item }}" when: server_firewall_backend == 'firewalld' - name: Allow server ports through firewalld tags: [services, packages] ansible.posix.firewalld: port: "{{ item }}" zone: "{{ server_firewalld_zone }}" state: enabled permanent: true immediate: true loop: "{{ server_firewalld_ports | default([]) }}" loop_control: label: "{{ item }}" when: server_firewall_backend == 'firewalld'