---
# Common baseline applied to both prod hosts: Docker engine, a non-sudo deploy
# service account, SSH hardening, a default-deny firewall, fail2ban, unattended
# security upgrades and time sync. Every task is idempotent.

- name: Install base packages
  ansible.builtin.apt:
    name:
      - ca-certificates
      - curl
      - gnupg
      - ufw
      - fail2ban
      - unattended-upgrades
      - chrony
    state: present
    update_cache: true
    cache_valid_time: 3600

# --- Docker engine (official repo; trixie is published upstream) ---------------

- name: Create apt keyring directory
  ansible.builtin.file:
    path: /etc/apt/keyrings
    state: directory
    mode: "0755"

- name: Install Docker apt GPG key
  ansible.builtin.get_url:
    url: https://download.docker.com/linux/debian/gpg
    dest: /etc/apt/keyrings/docker.asc
    mode: "0644"

- name: Add Docker apt repository
  ansible.builtin.apt_repository:
    repo: >-
      deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.asc]
      https://download.docker.com/linux/debian {{ ansible_distribution_release }} stable
    filename: docker
    state: present

- name: Install Docker engine and the compose plugin
  ansible.builtin.apt:
    name:
      - docker-ce
      - docker-ce-cli
      - containerd.io
      - docker-buildx-plugin
      - docker-compose-plugin
    state: present
    update_cache: true

- name: Configure the Docker daemon (live-restore + log rotation)
  ansible.builtin.template:
    src: daemon.json.j2
    dest: /etc/docker/daemon.json
    mode: "0644"
  notify: restart docker

- name: Enable and start Docker
  ansible.builtin.service:
    name: docker
    enabled: true
    state: started

# --- Deploy service account ----------------------------------------------------

- name: Create the deploy service account
  ansible.builtin.user:
    name: "{{ deploy_user }}"
    groups: docker
    append: true
    shell: /bin/bash
    create_home: true

- name: Ensure the deploy .ssh directory
  ansible.builtin.file:
    path: "/home/{{ deploy_user }}/.ssh"
    state: directory
    owner: "{{ deploy_user }}"
    group: "{{ deploy_user }}"
    mode: "0700"

- name: Authorize the CI deploy SSH key (exclusive)
  ansible.builtin.copy:
    dest: "/home/{{ deploy_user }}/.ssh/authorized_keys"
    content: "{{ deploy_ci_pubkey }}\n"
    owner: "{{ deploy_user }}"
    group: "{{ deploy_user }}"
    mode: "0600"

# --- SSH hardening -------------------------------------------------------------

- name: Harden sshd (key-only auth)
  ansible.builtin.template:
    src: sshd-hardening.conf.j2
    dest: /etc/ssh/sshd_config.d/10-scrabble-hardening.conf
    mode: "0644"
    validate: sshd -t -f %s
  notify: reload sshd

# --- Firewall (default deny incoming) ------------------------------------------
# SSH is allowed before the policy flips so enabling ufw never locks us out.

- name: Allow SSH through the firewall
  community.general.ufw:
    rule: allow
    name: OpenSSH

- name: Default-deny incoming, allow outgoing
  community.general.ufw:
    direction: "{{ item.direction }}"
    policy: "{{ item.policy }}"
  loop:
    - { direction: incoming, policy: deny }
    - { direction: outgoing, policy: allow }

- name: Enable the firewall
  community.general.ufw:
    state: enabled

# --- fail2ban ------------------------------------------------------------------

- name: Configure the fail2ban sshd jail
  ansible.builtin.template:
    src: jail.local.j2
    dest: /etc/fail2ban/jail.local
    mode: "0644"
  notify: restart fail2ban

- name: Enable and start fail2ban
  ansible.builtin.service:
    name: fail2ban
    enabled: true
    state: started

# --- Unattended security upgrades + time sync ----------------------------------

- name: Enable unattended upgrades
  ansible.builtin.copy:
    dest: /etc/apt/apt.conf.d/20auto-upgrades
    mode: "0644"
    content: |
      APT::Periodic::Update-Package-Lists "1";
      APT::Periodic::Unattended-Upgrade "1";

- name: Enable and start chrony
  ansible.builtin.service:
    name: chrony
    enabled: true
    state: started

# --- Deploy directories --------------------------------------------------------

- name: Create the scrabble base directories
  ansible.builtin.file:
    path: "{{ scrabble_base_dir }}/{{ item }}"
    state: directory
    owner: "{{ deploy_user }}"
    group: "{{ deploy_user }}"
    mode: "0750"
  loop:
    - ""
    - config
    - certs
    - dumps
    - images
