1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
|
Ansible Role: BorgBackup
========================
An Ansible role that installs and configures a systemd service for BorgBackup on
a client and (delegated) server.
This allows you to very easily add backups to your hosts.
The documentation assumes basic knowledge about BorgBackup. You can get up to
speed with Borg by reading their excellent documentation on
<https://borgbackup.readthedocs.io>.
How it works
------------
```mermaid
sequenceDiagram
participant Ansible
participant borg-client
participant borg-server
Ansible->>borg-server: Install dependencies
Ansible->>borg-client: Install dependencies
Ansible->>borg-server: Setup Repository
Ansible->>borg-client: Setup Repository
Ansible->>borg-client: Setup backup job
borg-client->>Ansible: Store decryption keys
borg-client-->borg-server: Do Backup
```
Installation
------------
via ansible-galaxy
```sh
ansible-galaxy collection install kliwniloc.borgbackup
```
```yaml
# requirements.yml
- src: kliwniloc.borgbackup
```
via git
```sh
ansible-galaxy collection install git+https://github.com/kliwniloc/ansible-role-borgbackup.git,master
```
```yaml
# requirements.yml
- src: https://github.com/kliwniloc/ansible-role-borgbackup
version: master
name: kliwniloc.borgbackup
```
Role Variables
--------------
For more details, see: [`defaults/main.yml`](defaults/main.yml)
You need to specify your Borg hostname (as defined in your Ansible inventory)
as well as the public SSH key from that Borg SSH server.
You can get this key by scanning the Borg server host like this:
`ssh-keyscan -t rsa borg.example.org` and removing the hostname, so the output
looks like this:
`ssh-rsa AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA...`.
If the Ansible hostname is not reachable from the client host, you must set
`borg_server_host_url` to a host that is reachable from the Borg clients. It
will default to `borg_server_host`.
> - `borg_server_host` is used by Ansible to delegate tasks to the Borg server
> - `borg_server_host_url` is used by the client to connect to the Borg server
```yaml
borg_server_host: "" # Required
borg_server_host_ssh_key: "" # Required
borg_server_host_url: {{ borg_server_host }} # Optional
```
The role creates a user for the Borg repositories on the Borg server. You can
specify the location of the home directory with `borg_server_user_home`, which
will also be the location for the backups.
```yaml
borg_server_user_home: /opt/borg
```
For the backup itself, there are a few Borg parameters you can configure.
Not all options that Borg offers are available in the Ansible role yet. For more
configuration options, see <https://borgbackup.readthedocs.io>.
`borg_repo_name` configures the name of the repository as it is created on the
Borg server in the `borg_server_user_home` directory. By default, we use the
inventory hostname, which is fine if you don't use multiple Borg repositories on
the same client and server hosts.
The individual backup names can be customized in the `borg_backup_name_format`
variable. You can use placeholders such as `{hostname}` for the backups, see:
<https://borgbackup.readthedocs.io/en/stable/usage/help.html#borg-help-placeholders>.
`borg_mode_append_only` restricts the deletion of the backups from the client.
This can increase security but comes at the cost of not being able to clean up
old backups from the client.
```yaml
borg_repo_name: "{{ inventory_hostname }}"
borg_backup_name_format: "{hostname}-{now:%Y-%m-%dT%H:%M:%S}"
borg_mode_append_only: false # Server side append only config
```
We use zstd compression by default, but you can change it to any of the
supported modes see:
<https://borgbackup.readthedocs.io/en/stable/usage/help.html#borg-help-compression>.
You can configure a passphrase for the encryption keys in `borg_passphrase`of
your Borg backups, but it is not used by default.
`borg_included_dirs` and `borg_excluded_dirs` finally picks what directories
will be backed up by Borg.
```yaml
borg_compression: zstd # -C argument
borg_passphrase: "" # Env variable
borg_included_dirs: [] # Positional arguments
borg_excluded_dirs: [] # --exclude arguments
```
To decrypt your backups without the client, we store the decryption keys in a
YAML file in your Ansible repository. You require the decryption keys as well as
access to the repository files on the Borg server to access the backups.
If you wish to add another layer of security for these decryption keys, consider
using git encryption tools like <https://github.com/AGWA/git-crypt> or storing
the keys in a secure location outside of git.
```yaml
borg_decryption_keys_yaml_path: "{{ inventory_dir }}/decryption_keys.yml"
```
The scheduling of the backups is done via systemd. For this purpose a systemd
service and a corresponding timer are created.
Additionally, we create backup scripts for use in the systemd service and for
the ability to easily trigger manual backups.
To support multiple backups (with different schedules), we have the
`borg_backup_argument` which defaults to `{{ borg_server_host_url }}` and should
be unique per backup target.
The names of the systemd service and timer are:
`{{ borg_backup_timer_name }}{{ borg_backup_argument }}.service` and
`{{ borg_backup_timer_name }}{{ borg_backup_argument }}.timer`.
For the backup scripts we add `{{ borg_backup_script_location }}` for creating a
backup on all specified targets and
`{{ borg_backup_script_location }}{{ borg_backup_argument }}` for backing up to
each target.
To configure the backup schedule, we offer `borg_systemd_oncalendar` and
`borg_systemd_accuracysec`, which map to the corresponding systemd options,
see man-page systemd.timer(5).
```yaml
borg_backup_script_location: /usr/local/bin/run_borg_backup
borg_backup_timer_name: borg_backup
borg_backup_service_name: borg_backup
borg_backup_argument: '{{ borg_server_host_url }}'
borg_systemd_oncalendar: '*-*-* 02:00:00'
borg_systemd_accuracysec: 60min
```
Example Playbooks
-----------------
Simple Playbook
```yaml
- name: >
Add Borg backup to the borg-client and save the
decryption keys alongside the playbook
hosts: borg-client
roles:
- role: kliwniloc.borgbackup
borg_server_host: borg-server
borg_server_host_ssh_key: ssh-rsa AAAAAAAA...
borg_decryption_keys_yaml_path: "{{ playbook_dir }}/decryption_keys.yml"
borg_included_dirs:
- /home
- /opt/project
```
Multiple Backup servers
```yaml
- name: >
Add Borg backup with multiple borg servers to the borg-client and
save the decryption keys alongside the playbook
hosts: borg-client
vars:
borg_included_dirs:
- /home
- /opt/project
roles:
- role: kliwniloc.borgbackup
borg_server_host: borg-server1
borg_server_host_ssh_key: ssh-rsa AAAAAAAA...
- role: kliwniloc.borgbackup
borg_server_host: borg-server2
borg_server_host_ssh_key: ssh-rsa BBBBBBBB...
```
Dependencies
------------
None.
License
-------
MIT
|