---
- name: Verify assertions
  assert:
    that:
      - ansible_distribution == "Debian"
      - ansible_distribution_major_version|int >= 10
      - ansible_service_mgr == "systemd"

- name: Disable cgroup2 for Docker
  lineinfile:
    backup: true
    line: |-
      GRUB_CMDLINE_LINUX_DEFAULT="quiet systemd.unified_cgroup_hierarchy=0"
    path: /etc/default/grub
  notify:
    - Update GRUB

- name: Enable the backports repo
  loop:
    - deb
    - deb-src
  apt_repository:
    # yamllint disable-line rule:line-length
    repo: '{{ item }} http://deb.debian.org/debian {{ ansible_distribution_release }}-backports main contrib non-free'
    state: present
    update_cache: true

- name: Set normal priority for the backports repo
  copy:
    content: |
      Package: *
      Pin: release  o=Debian Backports
      Pin-Priority: 500
    dest: /etc/apt/preferences.d/backports
    group: root
    mode: 0o644
    owner: root

- name: Install packages
  apt:
    cache_valid_time: 3600
    name:
      - amd64-microcode
      - btrfs-progs
      - cryptsetup
      - curl
      - docker.io
      - fwupd
      - git
      - intel-microcode
      - libpam-mount-bin
      - make
      - python3-cryptography
      - rsync
      - tmux
      - ufw
    state: present

- name: Copy the script to start stopped container after a restart
  copy:
    dest: /usr/share/docker.io/restart-containers
    mode: preserve
    src: docker-restart

- name: Create a drop-in directory for the Docker service
  file:
    path: /etc/systemd/system/docker.service.d
    mode: 0o0755
    state: directory

- name: Restart stopped containers after a restart
  copy:
    content: |
      [Service]
      ExecStartPost=/usr/share/docker.io/restart-containers
    dest: /etc/systemd/system/docker.service.d/restart-containers.conf
    mode: 0o0644
  notify:
    - Systemd daemon reload

- name: Rate limit SSH
  community.general.ufw:
    rule: limit
    port: ssh
    proto: tcp

- name: Allow default Docker network access to local services
  community.general.ufw:
    direction: in
    interface: docker0
    rule: allow

- name: Enable UFW
  community.general.ufw:
    default: reject
    state: enabled

- name: Allow unprivileged user namespaces
  ansible.posix.sysctl:
    name: kernel/unprivileged_userns_clone
    state: present
    value: "1"

- name: Allow more inotify watches
  ansible.posix.sysctl:
    name: fs.inotify.max_user_watches
    state: present
    value: "640000"

- name: Configure the SSH daemon
  include_tasks:
    file: '{{ playbook_dir }}/tasks/sshd_config.yaml'
  tags:
    - always

- name: Make /tmp a tmpfs mount
  ansible.posix.mount:
    fstype: tmpfs
    name: /tmp
    src: none
    opts: "defaults,nosuid,nodev"
    state: present

- name: Disable swap
  lineinfile:
    backup: true
    path: /etc/fstab
    regexp: swap
    state: absent

- name: Set UID/GID mapping range
  loop:
    - /etc/subgid
    - /etc/subuid
  copy:
    content: |
      nimrod:100000:65536
    dest: |-
      {{ item }}
    group: root
    mode: 0o0644
    owner: root

- name: Create my www directory
  file:
    group: www-data
    mode: 0o0755
    owner: www-data
    path: /var/www
    state: directory

- name: Create an SSL directory under /var
  file:
    group: root
    mode: 0o0755
    owner: root
    path: /var/ssl
    state: directory

# I know that I can use Ansible modules instead of calling OpenSSL directly, but
# with the command module I can easily skip the task if the private key or the
# certificate already exist. The point is to create an SSL and self-signed
# certificate only as a bootstrap step. Once there is an existing (and assumed
# valid) certificate, don't overwrite it.

- name: Create private SSL key
  command:
    cmd: openssl genrsa -out /var/ssl/site.key 4096
    creates: /var/ssl/site.key

- name: Make sure the private key is accessible
  file:
    mode: 0o0444
    path: /var/ssl/site.key
    state: file

- name: Create SSL certificate
  command:
    cmd: >-
      openssl
      req
      -x509
      -out /var/ssl/site.crt
      -nodes
      -key /var/ssl/site.key
      -batch
    creates: /var/ssl/site.crt

- name: Create Diffie-Hellman Parameters file
  community.crypto.openssl_dhparam:
    force: false
    mode: 0o0644
    path: /var/ssl/dhparams
    size: 4096
    state: present

- name: Copy btrfs copy script
  copy:
    dest: /usr/local/sbin/btrfs-backup
    group: root
    mode: preserve
    owner: root
    src: btrfs-backup

- name: Mail aliases
  loop:
    - root
    - nimrod
  ansible.builtin.lineinfile:
    backup: true
    create: true
    line: '{{ item }}: {{ item }}@shore.co.il'
    path: /etc/aliases
    regexp: '^{{ item }}:'
    state: present

- name: Copy update script
  ansible.builtin.copy:
    dest: /usr/local/sbin/daily
    mode: 0o0755
    src: daily

- name: Copy update service and timer
  loop:
    - update.service
    - update.timer
  ansible.builtin.copy:
    dest: /etc/systemd/system
    mode: 0o0644
    src: '{{ item }}'

- name: Enable the update timer
  ansible.builtin.systemd:
    enabled: true
    name: update.timer
    state: started

- name: Copy the btrfs scrub script
  ansible.builtin.copy:
    dest: /usr/local/sbin/btrfs-scrub
    mode: 0o0755
    src: btrfs-scrub

- name: Copy btrfs scrub service and timer
  loop:
    - scrub.service
    - scrub.timer
  ansible.builtin.copy:
    dest: /etc/systemd/system
    mode: 0o0644
    src: '{{ item }}'

- name: Enable the btrfs scrub timer
  ansible.builtin.systemd:
    enabled: true
    name: scrub.timer
    state: started
