feat(backup): add restic backup role with encrypted incremental snapshots
Restic-backed backups using a many-to-many repository/job model. - repository = destination: restic repository URL verbatim (s3, local, removable device), backend credentials via env passthrough, retention policy, and an optional per-repository ntfy notify channel - job = source set: paths, sqlite and postgres dumps (consistent .backup / pg_dump instead of torn live-file copies), pushed to one or more repos - systemd timer per job, per-repo + per-job flock serialisation, restic check with read_data_subset for rotating integrity verification Service roles declare what to back up (ntfy_backup_*, uptime_kuma_backup_*); the inventory declares where.
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
---
|
||||
# Included per repository with `repo` set to the repository dict.
|
||||
|
||||
- name: Deploy repository environment for {{ repo.name }}
|
||||
ansible.builtin.template:
|
||||
src: repo.env.j2
|
||||
dest: "{{ backup_config_dir }}/repos/{{ repo.name }}.env"
|
||||
owner: root
|
||||
group: root
|
||||
mode: "0600"
|
||||
no_log: true
|
||||
|
||||
- name: Create local repository directory for {{ repo.name }}
|
||||
ansible.builtin.file:
|
||||
path: "{{ repo.repository }}"
|
||||
state: directory
|
||||
owner: root
|
||||
group: root
|
||||
mode: "0700"
|
||||
when: backup_repo_is_local | bool
|
||||
|
||||
- name: Create device mountpoint for {{ repo.name }}
|
||||
ansible.builtin.file:
|
||||
path: "{{ repo.mountpoint }}"
|
||||
state: directory
|
||||
owner: root
|
||||
group: root
|
||||
mode: "0700"
|
||||
when: backup_repo_is_device | bool
|
||||
|
||||
# Device repositories are initialised lazily by the backup script the first
|
||||
# time the disk is actually attached. Everything else is initialised here so
|
||||
# that bad credentials or an unreachable endpoint fail at deploy time rather
|
||||
# than at 03:00 on a Sunday.
|
||||
- name: Check initialisation state of repository {{ repo.name }}
|
||||
ansible.builtin.command:
|
||||
cmd: restic cat config
|
||||
environment: "{{ backup_repo_environment }}"
|
||||
register: backup_repo_state
|
||||
failed_when: false
|
||||
changed_when: false
|
||||
no_log: true
|
||||
when: not backup_repo_is_device | bool
|
||||
|
||||
- name: Initialise repository {{ repo.name }}
|
||||
ansible.builtin.command:
|
||||
cmd: restic init
|
||||
environment: "{{ backup_repo_environment }}"
|
||||
when:
|
||||
- not backup_repo_is_device | bool
|
||||
- backup_repo_state.rc | default(1) != 0
|
||||
changed_when: true
|
||||
no_log: true
|
||||
Reference in New Issue
Block a user