Encrypt borg repos with repokey-blake2 + shared passphrase

borg_passphrase is required (Semaphore secret, same across hosts).
The role writes it to /etc/borgmatic/passphrase (0600 root) and
configures borgmatic to use BORG_PASSCOMMAND=cat /etc/borgmatic/passphrase,
and runs `borg init --encryption=repokey-blake2` with BORG_PASSPHRASE in
the env. no_log on the tasks that touch the passphrase.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-15 21:58:14 +02:00
parent 885a617388
commit 54e111338d
2 changed files with 22 additions and 2 deletions
+4 -1
View File
@@ -120,9 +120,12 @@
- name: Initialize borg repository (no-op if already initialized)
ansible.builtin.command:
cmd: borg init --encryption=none {{ borgcontroller_repo_uri }}
cmd: borg init --encryption=repokey-blake2 {{ borgcontroller_repo_uri }}
environment:
BORG_PASSPHRASE: "{{ borg_passphrase }}"
register: _borg_init
changed_when: _borg_init.rc == 0
failed_when:
- _borg_init.rc != 0
- "'already exists' not in (_borg_init.stderr | default(''))"
no_log: true
+18 -1
View File
@@ -8,6 +8,13 @@
when: inventory_hostname in (backup_hosts | default({}))
block:
- name: Ensure borg_passphrase is set (Semaphore secret)
ansible.builtin.assert:
that:
- borg_passphrase is defined
- borg_passphrase | length > 0
fail_msg: "borg_passphrase must be defined (provided by Semaphore secrets)"
- name: Install borgmatic
ansible.builtin.package:
name: borgmatic
@@ -21,6 +28,15 @@
group: root
mode: '0750'
- name: Write borg passphrase file
ansible.builtin.copy:
dest: /etc/borgmatic/passphrase
content: "{{ borg_passphrase }}"
owner: root
group: root
mode: '0600'
no_log: true
- name: Ensure root has an SSH key for the borg server
ansible.builtin.user:
name: root
@@ -36,7 +52,7 @@
- borgcontroller_username is defined
- borgcontroller_password is defined
- name: Build borgmatic config (strip controller-only keys, inject repository)
- name: Build borgmatic config (strip controller-only keys, inject repository + passcommand)
ansible.builtin.set_fact:
_borgmatic_config: >-
{{
@@ -44,6 +60,7 @@
| dict2items
| rejectattr('key', 'in', ['storage_size_gb'])
| items2dict)
| combine({'encryption_passcommand': 'cat /etc/borgmatic/passphrase'})
| combine(
{'repositories': [{'path': borgcontroller_repo_uri, 'label': inventory_hostname}]}
if borgcontroller_repo_uri is defined else {}