# SPDX-FileCopyrightText: 2026 Matthew Fennell # # SPDX-License-Identifier: AGPL-3.0-or-later --- - name: Ensure all authorized keys are copied to root account remote_user: root ansible.posix.authorized_key: key: | {% for key in authorized_key_files %} {{ lookup('file', key) }} {% endfor %} user: root exclusive: true # Now, we create a non-root user with sudo privileges - name: Ensure wheel group exists remote_user: root ansible.builtin.group: name: wheel state: present - name: Ensure wheel group allows passwordless sudo remote_user: root ansible.builtin.lineinfile: dest: /etc/sudoers state: present regexp: "^%wheel" line: "%wheel ALL=(ALL) NOPASSWD: ALL" validate: visudo -cf %s - name: Ensure non-root admin account is created in wheel group remote_user: root ansible.builtin.user: name: admin groups: wheel shell: /bin/bash append: true - name: Ensure admin ssh directory exists remote_user: root ansible.builtin.file: path: /home/admin/.ssh state: directory owner: admin group: admin mode: "0700" - name: Copy authorised keys to admin account remote_user: root ansible.builtin.copy: src: /root/.ssh/authorized_keys dest: /home/admin/.ssh/authorized_keys remote_src: true owner: admin group: admin mode: preserve - name: Ensure cloud-init is disabled ansible.builtin.copy: content: "" dest: /etc/cloud/cloud-init.disabled force: false owner: root group: root mode: "0644" become: true - name: Ensure hostname is set ansible.builtin.hostname: name: "{{ hostname }}" become: true - name: Ensure hostname is configured in /etc/hosts ansible.builtin.template: src: hosts.j2 dest: /etc/hosts owner: root group: root mode: "0644" become: true # This is needed by ansible.builtin.deb822_repository to interact with the # sources lists. In ansible-core 2.20 and above, there is a builtin # install_python_debian parameter that handles that without this extra step, # but we are currently running 2.19. # TODO(debian-forky) use deb822_repository's install_python_debian parameter - name: Ensure python3-debian is installed ansible.builtin.apt: name: - python3-debian state: present update_cache: true become: true - name: Ensure debian apt repositories are configured ansible.builtin.deb822_repository: name: debian uris: "{{ debian_uri }}" suites: - "{{ debian_version }}" - "{{ debian_version }}-updates" components: main signed_by: /usr/share/keyrings/debian-archive-keyring.gpg become: true - name: Ensure debian-security apt repositories are configured ansible.builtin.deb822_repository: name: debian-security uris: "{{ debian_security_uri }}" suites: "{{ debian_version }}-security" components: main signed_by: /usr/share/keyrings/debian-archive-keyring.gpg become: true - name: Ensure required packages are installed ansible.builtin.apt: name: - rsync # Backups - systemd-timesyncd # Used to make sure the date is correct - ufw # Firewall - unattended-upgrades # Not every hosting provider installs by default state: present update_cache: true become: true # Vultr adds a custom sshd_config file that enabled password authentication. # I don't want this to be enabled, since I'm already copying the public key. - name: Ensure password authentication is not explicitly enabled ansible.builtin.file: path: "/etc/ssh/sshd_config.d/50-cloud-init.conf" state: absent become: true notify: Restart sshd - name: Ensure password based authentication is disabled ansible.builtin.copy: src: 50-disable-password-auth.conf dest: "/etc/ssh/sshd_config.d/50-disable-password-auth.conf" owner: root group: root mode: "0644" become: true notify: Restart sshd - name: Ensure unattended upgrades config is installed ansible.builtin.copy: src: 50unattended-upgrades dest: "/etc/apt/apt.conf.d/50unattended-upgrades" owner: root group: root mode: "0644" become: true