platform/platform-infra/ansible/roles/backup/tasks/main.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

175 lines
4.8 KiB
YAML

---
# ── ZFS snapshots (files stream) via sanoid ─────────────────────────────────
- name: Install sanoid (snapshots + syncoid replication)
ansible.builtin.apt:
name: sanoid
state: present
when: backup_snapshots_enabled
- name: Configure sanoid snapshot policy
ansible.builtin.template:
src: sanoid.conf.j2
dest: /etc/sanoid/sanoid.conf
owner: root
group: root
mode: "0644"
when: backup_snapshots_enabled
- name: Enable the sanoid timer
ansible.builtin.systemd:
name: sanoid.timer
enabled: true
state: started
when: backup_snapshots_enabled
# ── Per-database dumps (DB stream) ──────────────────────────────────────────
- name: Install the DB backup script
ansible.builtin.template:
src: heleos-db-backup.sh.j2
dest: /usr/local/sbin/heleos-db-backup.sh
owner: root
group: root
mode: "0755"
when: db_backup_enabled
- name: Install the DB backup service + timer
ansible.builtin.copy:
dest: "/etc/systemd/system/{{ item.name }}"
owner: root
group: root
mode: "0644"
content: "{{ item.content }}"
loop:
- name: heleos-db-backup.service
content: |
[Unit]
Description=heleos per-database dumps (rotated)
After=docker.service
Requires=docker.service
[Service]
Type=oneshot
ExecStart=/usr/local/sbin/heleos-db-backup.sh
- name: heleos-db-backup.timer
content: |
[Unit]
Description=Run heleos DB backups on a schedule
[Timer]
OnCalendar={{ db_backup_oncalendar }}
Persistent=true
[Install]
WantedBy=timers.target
loop_control:
label: "{{ item.name }}"
when: db_backup_enabled
notify: Reload systemd
- name: Enable the DB backup timer
ansible.builtin.systemd:
name: heleos-db-backup.timer
enabled: true
daemon_reload: true
state: started
when: db_backup_enabled
# ── Offsite: files (syncoid / zfs send) ─────────────────────────────────────
- name: Install the ZFS offsite script
ansible.builtin.template:
src: heleos-zfs-offsite.sh.j2
dest: /usr/local/sbin/heleos-zfs-offsite.sh
owner: root
group: root
mode: "0755"
when: zfs_offsite_target | length > 0
- name: Install the ZFS offsite service + timer
ansible.builtin.copy:
dest: "/etc/systemd/system/{{ item.name }}"
owner: root
group: root
mode: "0644"
content: "{{ item.content }}"
loop:
- name: heleos-zfs-offsite.service
content: |
[Unit]
Description=heleos offsite ZFS replication (syncoid)
[Service]
Type=oneshot
ExecStart=/usr/local/sbin/heleos-zfs-offsite.sh
- name: heleos-zfs-offsite.timer
content: |
[Unit]
Description=Run heleos offsite ZFS replication on a schedule
[Timer]
OnCalendar={{ zfs_offsite_oncalendar }}
Persistent=true
[Install]
WantedBy=timers.target
loop_control:
label: "{{ item.name }}"
when: zfs_offsite_target | length > 0
notify: Reload systemd
- name: Enable the ZFS offsite timer
ansible.builtin.systemd:
name: heleos-zfs-offsite.timer
enabled: true
daemon_reload: true
state: started
when: zfs_offsite_target | length > 0
# ── Offsite: DB dumps (rsync) ───────────────────────────────────────────────
- name: Install the DB offsite script
ansible.builtin.template:
src: heleos-db-offsite.sh.j2
dest: /usr/local/sbin/heleos-db-offsite.sh
owner: root
group: root
mode: "0755"
when: db_offsite_target | length > 0
- name: Install the DB offsite service + timer
ansible.builtin.copy:
dest: "/etc/systemd/system/{{ item.name }}"
owner: root
group: root
mode: "0644"
content: "{{ item.content }}"
loop:
- name: heleos-db-offsite.service
content: |
[Unit]
Description=heleos offsite DB dump sync (rsync)
[Service]
Type=oneshot
ExecStart=/usr/local/sbin/heleos-db-offsite.sh
- name: heleos-db-offsite.timer
content: |
[Unit]
Description=Run heleos offsite DB sync on a schedule
[Timer]
OnCalendar={{ db_offsite_oncalendar }}
Persistent=true
[Install]
WantedBy=timers.target
loop_control:
label: "{{ item.name }}"
when: db_offsite_target | length > 0
notify: Reload systemd
- name: Enable the DB offsite timer
ansible.builtin.systemd:
name: heleos-db-offsite.timer
enabled: true
daemon_reload: true
state: started
when: db_offsite_target | length > 0