Add borg backup playbook/roles/tasks + Implement for Vaultwarden.
This commit is contained in:
parent
baab29b4a5
commit
e31b9b260d
12 changed files with 170 additions and 26 deletions
12
README.md
12
README.md
|
@ -18,3 +18,15 @@ sudo apt install -y certbot python3-certbot-dns-ovh
|
||||||
Copy the existing `secrets.yml.example` to `secrets.yml`, run `ansible-vault encrypt secrets.yml` to encrypt the file with a password, and finally edit the newly encrypted file with `ansible-vault edit secrets.yml`.
|
Copy the existing `secrets.yml.example` to `secrets.yml`, run `ansible-vault encrypt secrets.yml` to encrypt the file with a password, and finally edit the newly encrypted file with `ansible-vault edit secrets.yml`.
|
||||||
|
|
||||||
If you want to change the vault password run `ansible-vault rekey secrets.yml`.
|
If you want to change the vault password run `ansible-vault rekey secrets.yml`.
|
||||||
|
|
||||||
|
|
||||||
|
## Backups
|
||||||
|
Run the `backup-services.yml` playbook once to setup the passphrase file.
|
||||||
|
|
||||||
|
After that, you can create a root cronjob to run this playbook without requiring interactivity:
|
||||||
|
|
||||||
|
```
|
||||||
|
ANSIBLE_ROLES_PATH=/home/viyurz/vps/roles/ ansible-playbook /home/viyurz/vps/playbooks/backup-services.yml -e include_secrets=false -e selected_projects=''
|
||||||
|
```
|
||||||
|
|
||||||
|
Here we leave `selected_projects` empty to backup all projects.
|
||||||
|
|
19
env.yml
19
env.yml
|
@ -7,7 +7,10 @@ docker_projects_dir: "{{ ansible_env['HOME'] }}/docker-projects"
|
||||||
uid_shift: 99999
|
uid_shift: 99999
|
||||||
|
|
||||||
|
|
||||||
cifs_host: "{{ cifs_credentials['username'] }}.your-storagebox.de"
|
# cifs_credentials is undefined when we run the backup playbook
|
||||||
|
# as a cronjob, so set empty default value to prevent errors,
|
||||||
|
# which is fine because we don't use it.
|
||||||
|
cifs_host: "{{ cifs_credentials['username'] | default('') }}.your-storagebox.de"
|
||||||
|
|
||||||
cifs_mounts:
|
cifs_mounts:
|
||||||
backups:
|
backups:
|
||||||
|
@ -46,6 +49,20 @@ projects:
|
||||||
- vaultwarden
|
- vaultwarden
|
||||||
|
|
||||||
|
|
||||||
|
projects_to_backup:
|
||||||
|
- vaultwarden
|
||||||
|
|
||||||
|
|
||||||
|
borg_repodir: "{{ cifs_mounts['backups']['path'] }}/borg"
|
||||||
|
borg_passphrase_file: /etc/borg-passphrase.txt
|
||||||
|
borg_prune_options: |
|
||||||
|
--keep-within=1d
|
||||||
|
--keep-daily=7
|
||||||
|
--keep-weekly=4
|
||||||
|
--keep-monthly=12
|
||||||
|
--keep-yearly=10
|
||||||
|
|
||||||
|
|
||||||
# Ports exposed to host
|
# Ports exposed to host
|
||||||
ports:
|
ports:
|
||||||
coturn_listening: 3478
|
coturn_listening: 3478
|
||||||
|
|
31
playbooks/backup-services.yml
Normal file
31
playbooks/backup-services.yml
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
- name: Include variables files & run borg-init role
|
||||||
|
hosts: localhost
|
||||||
|
roles:
|
||||||
|
- include-vars
|
||||||
|
- borg-init
|
||||||
|
|
||||||
|
- name: Backup project(s)
|
||||||
|
hosts: localhost
|
||||||
|
vars:
|
||||||
|
run_backup: true
|
||||||
|
run_update: false
|
||||||
|
vars_prompt:
|
||||||
|
- name: selected_projects
|
||||||
|
prompt: "Choose projects to backup (leave empty to backup all. Projects list: {{ hostvars['localhost']['projects_to_backup'] }})"
|
||||||
|
private: false
|
||||||
|
unsafe: true
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: Backup project(s)
|
||||||
|
include_role:
|
||||||
|
name: "{{ project }}"
|
||||||
|
loop: "{{ (selected_projects | split) | default(projects_to_backup, true) }}"
|
||||||
|
loop_control:
|
||||||
|
# Do not use default variable name 'item' to prevent collisions with loops in roles.
|
||||||
|
loop_var: project
|
||||||
|
when: project in projects_to_backup
|
||||||
|
|
||||||
|
- name: Compact borg repository
|
||||||
|
hosts: localhost
|
||||||
|
roles:
|
||||||
|
- borg-compact
|
|
@ -6,6 +6,9 @@
|
||||||
|
|
||||||
- name: Update project(s)
|
- name: Update project(s)
|
||||||
hosts: localhost
|
hosts: localhost
|
||||||
|
vars:
|
||||||
|
run_backup: false
|
||||||
|
run_update: true
|
||||||
vars_prompt:
|
vars_prompt:
|
||||||
- name: selected_projects
|
- name: selected_projects
|
||||||
prompt: "Choose projects to update (Keep empty to update all. Projects list: {{ hostvars['localhost']['projects'] }})"
|
prompt: "Choose projects to update (Keep empty to update all. Projects list: {{ hostvars['localhost']['projects'] }})"
|
||||||
|
|
4
roles/borg-compact/tasks/main.yml
Normal file
4
roles/borg-compact/tasks/main.yml
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
- name: Compact borg repository
|
||||||
|
command:
|
||||||
|
cmd: "borg compact {{ borg_repodir }}"
|
||||||
|
become: true
|
35
roles/borg-init/tasks/main.yml
Normal file
35
roles/borg-init/tasks/main.yml
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
- name:
|
||||||
|
become: true
|
||||||
|
block:
|
||||||
|
- name: Install packages borgbackup & sqlite3
|
||||||
|
apt:
|
||||||
|
name:
|
||||||
|
- borgbackup
|
||||||
|
# SQLite required for Vaultwarden
|
||||||
|
- sqlite3
|
||||||
|
|
||||||
|
- name: Get borg passphrase file stat
|
||||||
|
stat:
|
||||||
|
path: "{{ borg_passphrase_file }}"
|
||||||
|
register: borg_stat_passphrase_file_result
|
||||||
|
|
||||||
|
- name: "Template borg-passphrase.txt to {{ borg_passphrase_file }}"
|
||||||
|
template:
|
||||||
|
src: borg-passphrase.txt
|
||||||
|
dest: "{{ borg_passphrase_file }}"
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: '600'
|
||||||
|
when: not borg_stat_passphrase_file_result.stat.exists or borg_update_passphrase | default(false) | bool
|
||||||
|
|
||||||
|
- name: Get borg repository stat
|
||||||
|
stat:
|
||||||
|
path: "{{ borg_repodir }}"
|
||||||
|
register: borg_stat_repodir_result
|
||||||
|
|
||||||
|
- name: Create borg repository
|
||||||
|
command:
|
||||||
|
cmd: "borg init --encryption repokey {{ borg_repodir }}"
|
||||||
|
environment:
|
||||||
|
BORG_PASSCOMMAND: "cat {{ borg_passphrase_file }}"
|
||||||
|
when: not borg_stat_repodir_result.stat.exists
|
1
roles/borg-init/templates/borg-passphrase.txt
Normal file
1
roles/borg-init/templates/borg-passphrase.txt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
{{ borg_passphrase }}
|
|
@ -5,3 +5,4 @@
|
||||||
- name: Include secrets from secrets.yml file
|
- name: Include secrets from secrets.yml file
|
||||||
include_vars:
|
include_vars:
|
||||||
file: "{{ playbook_dir }}/../secrets.yml"
|
file: "{{ playbook_dir }}/../secrets.yml"
|
||||||
|
when: include_secrets | default(true) | bool
|
||||||
|
|
29
roles/vaultwarden/tasks/backup.yml
Normal file
29
roles/vaultwarden/tasks/backup.yml
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
- name:
|
||||||
|
become: true
|
||||||
|
block:
|
||||||
|
- name: Backup SQLite database
|
||||||
|
command:
|
||||||
|
cmd: |
|
||||||
|
sqlite3
|
||||||
|
"{{ volumes['vaultwarden_datadir'] }}/db.sqlite3"
|
||||||
|
".backup {{ volumes['vaultwarden_datadir'] }}/db-backup.sqlite3"
|
||||||
|
|
||||||
|
- name: Create borg backup
|
||||||
|
command:
|
||||||
|
cmd: |
|
||||||
|
borg create
|
||||||
|
--compression=lzma
|
||||||
|
"{{ borg_repodir }}::{{ role_name }}-{now:%Y-%m-%d_%H-%M-%S}"
|
||||||
|
{{ volumes['vaultwarden_datadir'] }}/db-backup.sqlite3
|
||||||
|
environment:
|
||||||
|
BORG_PASSCOMMAND: "cat {{ borg_passphrase_file }}"
|
||||||
|
|
||||||
|
- name: Prune borg repository
|
||||||
|
command:
|
||||||
|
cmd: |
|
||||||
|
borg prune
|
||||||
|
--glob-archives='{{ role_name }}-*'
|
||||||
|
{{ borg_prune_options }}
|
||||||
|
{{ borg_repodir }}
|
||||||
|
environment:
|
||||||
|
BORG_PASSCOMMAND: "cat {{ borg_passphrase_file }}"
|
|
@ -1,26 +1,9 @@
|
||||||
- name: "Create {{ vaultwarden_project_dir }} project directory"
|
- name: Include backup tasks
|
||||||
file:
|
include_tasks:
|
||||||
path: "{{ vaultwarden_project_dir }}"
|
file: backup.yml
|
||||||
state: directory
|
when: run_backup | default(false) | bool
|
||||||
|
|
||||||
- name: Template docker-compose.yaml to project directory
|
- name: Include update tasks
|
||||||
template:
|
include_tasks:
|
||||||
src: docker-compose.yaml
|
file: update.yml
|
||||||
dest: "{{ vaultwarden_project_dir }}/docker-compose.yaml"
|
when: run_update | default(false) | bool
|
||||||
owner: "{{ ansible_env['USER'] }}"
|
|
||||||
group: "{{ ansible_env['USER'] }}"
|
|
||||||
mode: '640'
|
|
||||||
|
|
||||||
- name: "Create directory {{ volumes['vaultwarden_datadir'] }} with correct permissions"
|
|
||||||
file:
|
|
||||||
path: "{{ volumes['vaultwarden_datadir'] }}"
|
|
||||||
state: directory
|
|
||||||
owner: "{{ users['vaultwarden'] + uid_shift }}"
|
|
||||||
group: "{{ users['vaultwarden'] + uid_shift }}"
|
|
||||||
mode: '770'
|
|
||||||
become: true
|
|
||||||
|
|
||||||
- name: Pull/Create/Restart project services
|
|
||||||
community.docker.docker_compose:
|
|
||||||
project_src: "{{ vaultwarden_project_dir }}"
|
|
||||||
pull: "{{ docker_pull_images | bool }}"
|
|
||||||
|
|
26
roles/vaultwarden/tasks/update.yml
Normal file
26
roles/vaultwarden/tasks/update.yml
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
- name: "Create {{ vaultwarden_project_dir }} project directory"
|
||||||
|
file:
|
||||||
|
path: "{{ vaultwarden_project_dir }}"
|
||||||
|
state: directory
|
||||||
|
|
||||||
|
- name: Template docker-compose.yaml to project directory
|
||||||
|
template:
|
||||||
|
src: docker-compose.yaml
|
||||||
|
dest: "{{ vaultwarden_project_dir }}/docker-compose.yaml"
|
||||||
|
owner: "{{ ansible_env['USER'] }}"
|
||||||
|
group: "{{ ansible_env['USER'] }}"
|
||||||
|
mode: '640'
|
||||||
|
|
||||||
|
- name: "Create directory {{ volumes['vaultwarden_datadir'] }} with correct permissions"
|
||||||
|
file:
|
||||||
|
path: "{{ volumes['vaultwarden_datadir'] }}"
|
||||||
|
state: directory
|
||||||
|
owner: "{{ users['vaultwarden'] + uid_shift }}"
|
||||||
|
group: "{{ users['vaultwarden'] + uid_shift }}"
|
||||||
|
mode: '770'
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Pull/Create/Restart project services
|
||||||
|
community.docker.docker_compose:
|
||||||
|
project_src: "{{ vaultwarden_project_dir }}"
|
||||||
|
pull: "{{ docker_pull_images | bool }}"
|
|
@ -1,4 +1,6 @@
|
||||||
ansible_become_password:
|
ansible_become_password:
|
||||||
|
|
||||||
|
borg_passphrase:
|
||||||
|
|
||||||
cifs_credentials:
|
cifs_credentials:
|
||||||
username:
|
username:
|
||||||
|
|
Loading…
Reference in a new issue