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>
175 lines
4.8 KiB
YAML
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
|