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.
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.
firewall_ufw¶
Configures UFW with a deny-all inbound, allow-all outbound baseline. Opens specific TCP ports and source CIDRs as needed.
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:
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.
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: truefor 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.