borgbase / ansible-role-borgbackup

Ansible role to set up Borg and Borgmatic
MIT License
229 stars 102 forks source link

Enable separate cron jobs for multiple borgmatic configurations - avoid overwriting cronjob by multiple jobs #84

Closed michalroxorpl closed 2 years ago

michalroxorpl commented 3 years ago

The problem

I intent to run several different backups on same host. Currently it is not possible as after each run the role overwrites same cronjob filename /etc/cron.d/borgmatic updating it with only call of the currently processed borgmatic configuration file.

The scenario

There are several nextcloud instances hosted on one server. Each resides in separate directory. It is currently possible to create multiple borgmatic configurations to manage backups for all these nextcloud instances, however, after each playbook run, the /etc/cron.d/borgmatic file will be overwritten rendering the whole scenario unusable.

# inventory file
all:
  hosts:
  children:
[...]
    nextcloud:
      hosts:
        nc.firstdomain.tld:
          ncroot: /var/www/clients/client1/web10/web
          ncuser: web10
        nc.seconddomain.tld:
          ncroot: /var/www/clients/client2/web4/web
          ncuser: web4
        nc.thirddomain.tld:
          ncroot: /var/www/html/nextcloud/
          ncuser: www-data
        nc.fourthdomain.tld:
          ncroot: /var/www/clients/client4/web12/web
          ncuser: web12
        nc.fifthdomain.tld:
          ncroot: /var/www/clients/client5/web19/web
          ncuser: web19
        nc.sixthdomain.tld:
          ncroot: /var/www/clients/client3/web7/web
          ncuser: web7
[...]

The solution

Instead of using borgmatic_cron_name parsing to /etc/cron.d/borgmatic let's switch to name matching {{ borgmatic_config_name }} name in the cron job file name: borgmatic_cron_name parsing to /etc/cron.d/borgmatic-{{ borgmatic_config_name }}. With this approach we might successfully run the same playbook against one server for multiple backups, considering borgmatic_config_name will be different for each of the configurations.

The example

Example on how to approach this using configuration name based on inventory_hostname:

---
# External variables to be set:
# borgmatic_config_file
[...]
# borg_exclude_patterns
- hosts: '{{ servers }}'
  vars:
    borgmatic_config_file_fullname: "{{ borgmatic_config_file }}-{{ inventory_hostname }}"
    borgmatic_config_dir: /etc/borgmatic
    borgmatic_config_path: "{{ borgmatic_config_dir }}/{{ borgmatic_config_file_fullname }}"
[...]
  roles:
  - role: m3nu.ansible_role_borgbackup
    borgmatic_config_name: "{{ borgmatic_config_file_fullname }}"
m3nu commented 2 years ago

Hi, thanks for the contribution and sorry for the delay. Checking it out right now.

m3nu commented 2 years ago

You seem to have found a very simple workaround. Sadly the change isn't backwards-compatible and it would need another task to remove the old cron job or current users will end up with a duplicate cron job, which would be quite bad.

Since we already have the borgmatic_cron_name variable, is there anything stopping you from setting this variable in your own roles?

simonfojtu commented 2 years ago

I've been also wondering about similar scenario. My approach to solving it was to generate the borgmatic config files in /etc/borgmatic.d/ instead of in /etc/borgmatic. Then a single call to borgmatic will run all those configurations. Thus only one cron file is necessary if it's ok that they run at the same time (one after another).

See https://torsion.org/borgmatic/docs/how-to/make-per-application-backups/