Skip to content

Roles reference

All roles live in roles/. Each role has a defaults/main.yml with documented variables and a tasks/main.yml that does the work.

Overview

Role Used by Purpose
access_users web, db, tools, analytics Create OS users, install SSH keys, configure sudo
auditd web, db, tools, analytics Kernel audit daemon with baseline rules
cadvisor web cAdvisor container for Docker metrics
cloudflare web, db, tools, analytics Cloudflare Tunnels + Access applications
common_baseline all APT cache, base packages, timezone
cronjobs web, tools Deploy and schedule cron shell scripts
deployment web, tools Deployment user + directory setup
docker_compose_plugin web, analytics Docker Compose V2 plugin
docker_engine web, analytics Docker CE installation and configuration
fail2ban all SSH brute-force protection
firewall_ufw all UFW rules (inbound deny by default)
journald_limits web, db, tools, analytics systemd-journald retention limits
logrotate_custom web, db Custom log rotation for application logs
mariadb db MariaDB installation, hardening, users and databases
mariadb_binlog db Binary log configuration for point-in-time recovery
netdata web, db Netdata monitoring agent
sqlbak db SqlBak backup agent installation and server registration
ssh_hardening all sshd_config hardening (no root login, key-only auth, AllowUsers)
unattended_upgrades all Automatic security updates
verdaccio tools Private npm registry (Verdaccio)
verify_cloudflared web Assert cloudflared service is healthy before lockdown

Role details

access_users

Creates OS user accounts, adds SSH public keys, and configures sudo.

Users are defined in two ways that are merged together: 1. access_users – a flat list (defaults to [pt, sd] from group_vars/all/common.yml) 2. system.users – per-host structured users

# group_vars/all/common.yml
access_users:
  - name: pt
    groups: [sudo, docker]
    key_files:
      - keys/pt.pub
  - name: sd
    groups: [sudo, docker]
    key_files:
      - keys/sd.pub

# host_vars/bkdk-web-01/main.yml
system:
  users:
    - name: barberklingen
      sudo: true
      ssh:
        generation: true     # generate ed25519 key pair on server
        authorized_key: true # self-authorize the generated key
        connect: true        # add to SSH AllowUsers

Key files are resolved relative to the playbook root (the repo root). Store public keys in keys/.


auditd

Installs auditd and deploys a baseline ruleset that logs changes to: - Identity files (/etc/passwd, /etc/shadow, /etc/sudoers) - SSH config - Cron directories - Package management executables - Systemd and Docker binaries

auditd_enabled: true   # set to false in sandbox

# Append host-specific rules
auditd_extra_rules:
  - "-w /etc/mysql/ -p wa -k mysql"

cadvisor

Runs cAdvisor as a Docker container for exposing container resource metrics.

cadvisor_enabled: true
cadvisor_listen_port: 8080
cadvisor_image: "gcr.io/cadvisor/cadvisor:v0.49.1"

Waits for the Docker daemon to be ready before starting the container.


cloudflare

See the dedicated Cloudflare guide for full documentation.

Key defaults:

cloudflared_remote_config: true
cloudflared_create_tunnel: true
cloudflared_dns_proxied: true
cloudflare_application_session_duration: "24h"

common_baseline

Runs first on every host to establish a consistent baseline: - Removes any legacy Docker APT repository definitions that would conflict with the current setup. - Updates the APT cache. - Installs base packages: ca-certificates, curl, git, ufw, vim. - Sets the server timezone.

timezone: Etc/UTC
common_packages: []   # append additional packages here

cronjobs

Deploys cron shell scripts from cronjobs/ to /opt/cronjobs/<dir>/ and installs crontab entries for the site user.

Cron jobs are defined globally in group_vars/all/cronjobs.yml and enabled per-site in host_vars:

# group_vars/all/cronjobs.yml – job definitions
cronjobs:
  - name: wp-cron
    path: "/opt/cronjobs/{{ site.cronjob.dir }}/wp-cron.sh"
    timing: "*/5 * * * *"

# host_vars/bkdk-web-01/main.yml – enable per site
sites:
  - name: barberklingen
    cronjob:
      dir: barberklingen-dk
      enable:
        - name: wp-cron
        - name: as-global

deployment

Creates the deploy OS user with a generated SSH key pair and restricted sudo (limited to specific commands and paths). Used by CI/CD pipelines to deploy application code.

# group_vars/all/deployment.yml
system_users_base:
  - name: deploy
    groups: [sudo]
    ssh:
      authorized_keys: true
      create_keys: true

docker_engine

Installs Docker CE from the official Docker APT repository. Configures the Docker daemon and ensures the service is running and enabled.


docker_compose_plugin

Installs the Docker Compose V2 plugin (docker compose). Requires docker_engine to have run first.


fail2ban

Installs Fail2ban to block SSH brute-force attempts.

fail2ban_bantime: "1h"
fail2ban_findtime: "10m"
fail2ban_maxretry: 5

firewall_ufw

Configures UFW with a deny-all inbound, allow-all outbound baseline. Opens specific TCP ports and source CIDRs as needed.

ufw_default_incoming: deny
ufw_default_outgoing: allow
ufw_allow_tcp_ports: []   # e.g. [80, 443]

When zt_lockdown_enabled: true, the role allows no inbound ports (SSH is served via Cloudflare Tunnel only).

IP allowlists from group_vars/all/allowlist.yml are used to grant MySQL access from office IPs, Plecto, and Supermetrics CIDRs.


journald_limits

Configures systemd-journald to cap disk usage and retention:

journald_system_max_use: "500M"
journald_max_retention_sec: "7day"

Restarts journald if the config changes.


logrotate_custom

Deploys custom logrotate configurations for application log paths defined in sites[*].logrotate.system_logs_glob_paths.


mariadb

Installs MariaDB, hardens the installation (removes anonymous users, test databases), and manages databases and users declared in host variables.

Authentication for local root operations uses login_unix_socket (compatible with MariaDB's plugin-based auth). No root password prompt needed.

mariadb_bind_address: "0.0.0.0"   # set in group_vars/all/db.yml
mariadb_server_id: 1               # must be unique across all DB servers (used for replication)

mariadb_databases:
  - name: myapp_db
    collation: utf8mb4_unicode_ci
    encoding: utf8mb4

mariadb_users:
  - name: myapp
    host: "10.0.0.5"
    password: "{{ vault_myapp_db_password }}"
    priv: "myapp_db.*:ALL"

# Secrets in vault:
vault_mariadb_root_password: "..."

mariadb_binlog

Enables and configures binary logging for point-in-time recovery.

mariadb_binlog_enabled: true
mariadb_binlog_retention_days: 7
mariadb_binlog_format: "ROW"

netdata

Installs the Netdata monitoring agent for real-time system metrics. Enable the server integration per-host:

# host_vars/<hostname>/main.yml
system:
  netdata:
    active: true   # registers this server in the Netdata dashboard

sqlbak

Registers the server with SqlBak for automated database backups.

  • Downloads and runs the SqlBak install script (verified by SHA256).
  • Registers the server using sqlbak_server_key.
  • Configures a MariaDB connection for automated backups.
  • Uses no_log: true for registration commands to avoid leaking credentials.
# Secrets in group_vars/prod/db.vault.yml:
sqlbak_db_user: "sqlbak"
sqlbak_db_password: "..."
sqlbak_install_script_url: "https://..."
sqlbak_install_script_sha256: "..."

Idempotency: checks sqlbak --info to determine if the server is already registered before re-registering.


ssh_hardening

Writes a hardened sshd_config: - PermitRootLogin no - PasswordAuthentication no - PubkeyAuthentication yes - AllowUsers populated from system.ssh.allow_users

ssh_port: 22
ssh_permit_root_login: "no"
ssh_password_authentication: "no"
ssh_pubkey_authentication: "yes"

AllowUsers is computed dynamically from base_ssh_allow_users, access_users, system.users (with ssh.connect: true), and sites[*].user.


unattended_upgrades

Enables automatic security updates via unattended-upgrades. Only security patches are applied automatically; major package upgrades require manual intervention.


verdaccio

Installs and configures Verdaccio as a private npm registry on tool servers.


verify_cloudflared

Asserts that the cloudflared systemd service is active and healthy before the lockdown.yml playbook proceeds. Fails with a clear error if the tunnel is not running.

cloudflared_required: true   # set automatically by lockdown.yml