platform/platform-infra/ansible/group_vars/all.yml
Bart Van Geyt 0ade1c740f Phase 5: backup/DR automation (backup Ansible role)
Implements the two decoupled backup streams from docs/06 as an idempotent
Ansible role wired into the host playbook:

- Files: sanoid takes/prunes ZFS snapshots per policy (sanoid_datasets) on
  its packaged timer; syncoid replicates offsite (heleos-zfs-offsite),
  enabled only when zfs_offsite_target is set.
- DB: heleos-db-backup (nightly systemd timer) walks the deployments dir and
  dumps each DB-backed site via `docker exec mariadb-dump` into
  db-backups/<customer>/<site>/{daily,weekly,monthly} with rotation
  (automysqlbackup-style, adapted for the containerized DB; MYSQL_PWD keeps
  the password out of the process list). heleos-db-offsite rsyncs offsite
  when db_offsite_target is set.

Streams and schedules are configured in group_vars/all.yml; offsite is
opt-in via the two target vars. Updates doc 06 (implementation note), the
ansible README, and CLAUDE.md status. YAML + templates validated by render.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 18:04:41 +02:00

82 lines
4.2 KiB
YAML

# ─────────────────────────────────────────────────────────────────────────────
# heleos platform — host baseline variables (Phase 1)
# Edit these to match your environment before running the playbook.
# ─────────────────────────────────────────────────────────────────────────────
# --- General ----------------------------------------------------------------
host_timezone: "Europe/Brussels"
# --- ZFS --------------------------------------------------------------------
# The pool is created on a DEDICATED second virtual disk. Attach a disk to the
# VM first (e.g. /dev/sdb or /dev/vdb) and set it here.
#
# ⚠️ zpool create is DESTRUCTIVE to the target disk. The playbook refuses to
# touch a disk that already contains a filesystem/partition unless you set
# zfs_pool_force: true. For production prefer a stable /dev/disk/by-id/... path.
zfs_pool_name: tank
zfs_pool_disk: /dev/sdb
zfs_pool_force: false
zfs_compression: lz4 # lz4 (fast) or zstd (denser)
# Datasets created under the pool. Web roots and per-site/customer datasets are
# created later by the provisioning CLI (Phase 4); here we create the fixed
# platform datasets + the customers parent. See docs/03-naming-conventions.md.
zfs_child_datasets:
- { path: "platform" }
- { path: "platform/docker", mountpoint: "/var/lib/docker" }
- { path: "platform/mariadb" }
- { path: "platform/db-backups" }
- { path: "platform/traefik" }
- { path: "platform/forgejo" }
- { path: "platform/monitoring" }
- { path: "customers" }
# --- Docker -----------------------------------------------------------------
# Native ZFS storage driver keeps image layers as ZFS datasets under the pool
# (data-root sits on tank/platform/docker). Switch to overlay2 only if you have
# a specific reason.
docker_storage_driver: zfs
docker_data_root: /var/lib/docker
# Address pool for the many per-site bridge networks (avoids subnet exhaustion).
docker_address_pool_base: "10.201.0.0/16"
docker_address_pool_size: 24
# --- Firewall (nftables + Docker egress) ------------------------------------
ssh_port: 22
firewall_allowed_tcp_ports: [80, 443] # SSH is added automatically via ssh_port
# Outbound SMTP from containers is blocked (spam prevention from hacked sites).
smtp_blocked_ports: [25, 465, 587]
smtp_relay_host: "" # optional: allow SMTP only to this host
# --- SSH hardening ----------------------------------------------------------
# ⚠️ If ssh_disable_password_auth is true you MUST provide admin_authorized_keys
# for admin_user, or you will lock yourself out. The playbook asserts this.
admin_user: "{{ ansible_user }}"
admin_authorized_keys: [] # list of public key strings
ssh_disable_password_auth: false # flip to true once key login is verified
# --- Backups / DR (Phase 5) -------------------------------------------------
mariadb_container: mariadb
mariadb_env_file: /opt/heleos/platform-infra/stacks/mariadb/.env
deployments_dir: /opt/heleos/deployments
# ZFS snapshots via sanoid (files stream). Retention is per policy below.
backup_snapshots_enabled: true
sanoid_datasets:
- { name: "{{ zfs_pool_name }}/customers", recursive: true, hourly: 36, daily: 30, weekly: 8, monthly: 6 }
- { name: "{{ zfs_pool_name }}/platform", recursive: true, hourly: 0, daily: 14, weekly: 4, monthly: 3 }
# Per-database dumps (DB stream), automysqlbackup-style rotation via docker exec.
db_backup_enabled: true
db_backup_dir: "/{{ zfs_pool_name }}/platform/db-backups"
db_backup_oncalendar: "*-*-* 01:30:00"
db_backup_keep_daily: 14
db_backup_keep_weekly: 8
db_backup_keep_monthly: 6
# Offsite. Leave the targets empty to disable that stream.
zfs_offsite_target: "" # e.g. "user@backup-host:backup/heleos"
zfs_offsite_datasets: ["{{ zfs_pool_name }}/customers", "{{ zfs_pool_name }}/platform"]
zfs_offsite_oncalendar: "*-*-* 03:00:00"
db_offsite_target: "" # e.g. "user@backup-host:/srv/heleos/db-backups"
db_offsite_oncalendar: "*-*-* 03:30:00"