Compare commits

...

16 Commits

Author SHA1 Message Date
c847046720
refactor(mariadb): add state parameter and split container image arguments 2024-10-27 16:04:07 +01:00
d7b7c59f46
update(lego): bump version to 4.19.2 2024-10-23 20:48:59 +02:00
153df81836
feat(lego): Detect lego_architecture automatically 2024-10-18 14:53:59 +02:00
7021ed1a89
meta: bump collection version to 0.1.2, require community.docker@^3.0.0, take issues on codeberg repo mirror 2024-10-05 10:19:15 +02:00
afe72f554e
chore(nginx): add deployment_method=podman 2024-10-05 10:16:53 +02:00
c36e95d7eb
chore(nginx): add state=absent support 2024-10-05 10:14:35 +02:00
97526aec36
update(nginx): bump version to 1.27.2 2024-10-05 10:01:07 +02:00
fc73fdd1fa
fix(docs): typos and formatting 2024-09-21 11:36:21 +02:00
bd43f3963c
meta: bump collection version to 0.1.1 2024-09-21 11:11:36 +02:00
1076a9f384
update(mariadb): bump version to 10.11.9 2024-09-21 11:10:09 +02:00
82e69bdda3
update(nginx): bump version to 1.26.2 2024-09-21 11:08:57 +02:00
b9b5c19d38
update(lego): bump version to 4.18.0 2024-09-21 11:07:42 +02:00
b9e4abdf36
meta: require ansible >=2.15.0 2024-09-21 11:06:41 +02:00
aac6891518
meta: update collection version to 0.1.0, add community.docker as dependency 2024-09-21 10:58:40 +02:00
31d025ed75
docs: add READMEs to roles powerdns_tsig_key and dns 2024-09-21 10:57:46 +02:00
1423d2a243
feat(restic): add support for additional env vars, optional init and checking and pre-backup hooks 2024-09-18 18:20:12 +02:00
17 changed files with 278 additions and 60 deletions

View File

@ -13,6 +13,9 @@ and configuring basic system utilities like gnupg, ssh etc
- [`gnupg`](roles/gnupg/README.md): configures gnupg on the target system - [`gnupg`](roles/gnupg/README.md): configures gnupg on the target system
- [`lego`](roles/lego/README.md): runs [lego (LetsEncrypt Go)](https://github.com/go-acme/lego),
a ACME client written in go, using systemd (timers). Multi-instance capable.
- [`mariadb`](roles/mariadb/README.md): runs [MariaDB Server](https://mariadb.org/), one of the world's most popular open source relational database - [`mariadb`](roles/mariadb/README.md): runs [MariaDB Server](https://mariadb.org/), one of the world's most popular open source relational database
- [`minio`](roles/minio/README.md): Deploy [min.io](https://min.io), an - [`minio`](roles/minio/README.md): Deploy [min.io](https://min.io), an
@ -24,6 +27,9 @@ and configuring basic system utilities like gnupg, ssh etc
- [`restic`](roles/restic/README.md): Manage backups using restic - [`restic`](roles/restic/README.md): Manage backups using restic
and persist them to a configurable backend. and persist them to a configurable backend.
- [`powerdns_tsig_key`](roles/powerdns_tsig_key/README.md): Simple ansible role
for generating TSIG keys in PowerDNS.
## License ## License
[CNPLv7+](LICENSE.md): Cooperative Nonviolent Public License [CNPLv7+](LICENSE.md): Cooperative Nonviolent Public License

View File

@ -1,12 +1,22 @@
namespace: finallycoffee namespace: finallycoffee
name: base name: base
version: 0.0.2 version: 0.1.2
readme: README.md readme: README.md
authors: authors:
- transcaffeine <transcaffeine@finally.coffee> - transcaffeine <transcaffeine@finally.coffee>
description: Roles for base services which are common dependencies other services like databases description: Roles for base services which are common dependencies other services like databases
dependencies:
"community.docker": "^3.0.0"
license_file: LICENSE.md license_file: LICENSE.md
build_ignore: build_ignore:
- '*.tar.gz' - '*.tar.gz'
repository: https://git.finally.coffee/finallycoffee/base repository: https://git.finally.coffee/finallycoffee/base
issues: https://git.finally.coffee/finallycoffee/base/issues issues: https://codeberg.org/finallycoffee/ansible-collection-base/issues
tags:
- docker
- elastic
- lego
- mariadb
- minio
- nginx
- restic

View File

@ -1,3 +1,3 @@
--- ---
requires_ansible: ">=2.12" requires_ansible: ">=2.15"

33
roles/dns/README.md Normal file
View File

@ -0,0 +1,33 @@
# `finallycoffee.base.dns` ansible role
Simple role for wrapping around the
[`famedly.dns.update`](https://github.com/famedly/ansible-collection-dns/blob/main/plugins/modules/update.py)
ansible module.
## Usage
### Example playbook
```yaml
- target: "{{ target_hosts }}"
roles:
- role: finallycoffee.base.dns
vars:
dns_server: "dns.example.org"
dns_zone: "zone.example.org"
dns_records: "{{ dns_records }}"
dns_record_state: exact
dns_tsig_name: "mykeyname"
dns_tsig_algo: "hmac-sha256"
dns_tsig_key: "mykeycontent"
vars:
dns_records:
- type: A
name: gitea
content: "127.0.0.1"
- type: AAAA
name: gitea
content: "fe80::1"
- type: CNAME
name: "_acme_challenge.gitea"
content: "delegated-cname.challenge.example.org"
```

View File

@ -1,6 +1,6 @@
--- ---
lego_user: "lego" lego_user: "lego"
lego_version: "4.17.4" lego_version: "4.19.2"
lego_instance: default lego_instance: default
lego_base_path: "/opt/lego" lego_base_path: "/opt/lego"
lego_cert_user: "acme-{{ lego_instance }}" lego_cert_user: "acme-{{ lego_instance }}"
@ -58,7 +58,7 @@ lego_systemd_timer_name: "lego-{{ lego_instance }}.timer"
lego_systemd_timer_template: lego.timer.j2 lego_systemd_timer_template: lego.timer.j2
lego_systemd_timer_calendar: "*-*-* *:00/15:00" lego_systemd_timer_calendar: "*-*-* *:00/15:00"
lego_architecture: "amd64" lego_architecture: "{{ 'arm64' if ansible_architecture == 'aarch64' else 'amd64' }}"
lego_os: "linux" lego_os: "linux"
lego_binary_allow_net_bind_service: false lego_binary_allow_net_bind_service: false

View File

@ -1,8 +1,9 @@
--- ---
mariadb_version: "10.11.9"
mariadb_version: "10.11.6"
mariadb_base_path: /var/lib/mariadb mariadb_base_path: /var/lib/mariadb
mariadb_data_path: "{{ mariadb_base_path }}/{{ mariadb_version }}" mariadb_data_path: >-2
{{ mariadb_base_path }}/{{ mariadb_version | split('.') | first }}
mariadb_state: present
mariadb_root_password: ~ mariadb_root_password: ~
mariadb_database: ~ mariadb_database: ~
@ -13,10 +14,24 @@ mariadb_container_base_environment:
MARIADB_ROOT_PASSWORD: "{{ mariadb_root_password }}" MARIADB_ROOT_PASSWORD: "{{ mariadb_root_password }}"
mariadb_container_extra_environment: {} mariadb_container_extra_environment: {}
mariadb_container_name: mariadb mariadb_container_image_registry: docker.io
mariadb_container_image_name: docker.io/mariadb mariadb_container_image_namespace: ~
mariadb_container_image_name: mariadb
mariadb_container_image_tag: ~ mariadb_container_image_tag: ~
mariadb_container_image: "{{ mariadb_container_image_name }}:{{ mariadb_container_image_tag | default(mariadb_version, true) }}" mariadb_container_image: >-2
{{
([
mariadb_container_image_registry | default([], true),
mariadb_container_image_namespace | default([], true),
mariadb_container_image_name,
] | flatten | join('/'))
+ ':' + mariadb_container_image_tag | default(mariadb_version, true)
}}
mariadb_container_image_source: pull
mariadb_container_image_force_source: >-2
{{ mariadb_container_image_tag | default(false, true) | bool }}
mariadb_container_name: mariadb
mariadb_container_base_volumes: mariadb_container_base_volumes:
- "{{ mariadb_data_path }}:{{ mariadb_container_data_path }}:z" - "{{ mariadb_data_path }}:{{ mariadb_container_data_path }}:z"
mariadb_container_extra_volumes: [] mariadb_container_extra_volumes: []
@ -30,3 +45,5 @@ mariadb_container_environment: >-2
if (mariadb_database and mariadb_username and mariadb_password) if (mariadb_database and mariadb_username and mariadb_password)
else {}, recursive=True) else {}, recursive=True)
| combine(mariadb_container_extra_environment) }} | combine(mariadb_container_extra_environment) }}
mariadb_container_state: >-2
{{ (mariadb_state == 'present') | ternary('started', 'absent') }}

View File

@ -1,20 +1,21 @@
--- ---
- name: Ensure mariaDB container image is present on host - name: Ensure mariadb container image '{{ mariadb_container_image }}' is {{ mariadb_state }}
community.docker.docker_image: community.docker.docker_image:
name: "{{ mariadb_container_image }}" name: "{{ mariadb_container_image }}"
state: present state: "{{ mariadb_state }}"
source: pull source: "{{ mariadb_container_image_source }}"
force_source: "{{ mariadb_container_image_force_source }}"
- name: Ensure mariaDB {{ mariadb_version }} is running as '{{ mariadb_container_name }}' - name: Ensure mariadb container '{{ mariadb_container_name }}' is {{ mariadb_container_state }}
community.docker.docker_container: community.docker.docker_container:
name: "{{ mariadb_container_name }}" name: "{{ mariadb_container_name }}"
image: "{{ mariadb_container_image }}" image: "{{ mariadb_container_image }}"
env: "{{ mariadb_container_environment }}" env: "{{ mariadb_container_environment }}"
ports: "{{ mariadb_container_ports }}" ports: "{{ mariadb_container_ports | default(omit, true) }}"
labels: "{{ mariadb_container_labels }}" labels: "{{ mariadb_container_labels | default(omit, true) }}"
volumes: "{{ mariadb_container_volumes }}" volumes: "{{ mariadb_container_volumes }}"
networks: "{{ mariadb_container_networks | default(omit, true) }}" networks: "{{ mariadb_container_networks | default(omit, true) }}"
etc_hosts: "{{ mariadb_container_etc_hosts | default(omit, true) }}" etc_hosts: "{{ mariadb_container_etc_hosts | default(omit, true) }}"
purge_networks: "{{ mariadb_container_purge_networks | default(omit, true) }}" purge_networks: "{{ mariadb_container_purge_networks | default(omit, true) }}"
restart_policy: "{{ mariadb_container_restart_policy }}" restart_policy: "{{ mariadb_container_restart_policy }}"
state: started state: "{{ mariadb_container_state }}"

View File

@ -26,3 +26,8 @@ For exposing this server to the host and/or internet, the `nginx_container_ports
from host to container), `nginx_container_networks` (docker networking) or `nginx_container_labels` from host to container), `nginx_container_networks` (docker networking) or `nginx_container_labels`
(for label-based routing discovery like traefik) can be used. The options correspond to the arguments (for label-based routing discovery like traefik) can be used. The options correspond to the arguments
of the `community.docker.docker_container` module. of the `community.docker.docker_container` module.
## Deployment methods
Set `nginx_deployment_method` to either `docker` or `podman` to use the respective ansible modules for
creating and managing the container and its image. See all supported methods in `nginx_deployment_methods`.

View File

@ -1,9 +1,10 @@
--- ---
nginx_version: "1.27.2"
nginx_version: "1.25.3"
nginx_flavour: alpine nginx_flavour: alpine
nginx_base_path: /opt/nginx nginx_base_path: /opt/nginx
nginx_config_file: "{{ nginx_base_path }}/nginx.conf" nginx_config_file: "{{ nginx_base_path }}/nginx.conf"
nginx_state: present
nginx_deployment_method: docker
nginx_container_name: nginx nginx_container_name: nginx
nginx_container_image_reference: >- nginx_container_image_reference: >-
@ -26,6 +27,9 @@ nginx_container_image_repository: >-
nginx_container_image_registry: "docker.io" nginx_container_image_registry: "docker.io"
nginx_container_image_name: "nginx" nginx_container_image_name: "nginx"
nginx_container_image_tag: ~ nginx_container_image_tag: ~
nginx_container_image_source: pull
nginx_container_state: >-2
{{ (nginx_state == 'present') | ternary('started', 'absent') }}
nginx_container_restart_policy: "unless-stopped" nginx_container_restart_policy: "unless-stopped"
nginx_container_volumes: nginx_container_volumes:

12
roles/nginx/meta/main.yml Normal file
View File

@ -0,0 +1,12 @@
---
allow_duplicates: true
dependencies: []
galaxy_info:
role_name: nginx
description: Deploy nginx, a webserver
galaxy_tags:
- nginx
- http
- webserver
- docker
- podman

View File

@ -0,0 +1,28 @@
---
- name: Ensure docker container image '{{ nginx_container_image_reference }}' is {{ nginx_state }}
community.docker.docker_image:
name: "{{ nginx_container_image_reference }}"
state: "{{ nginx_state }}"
source: "{{ nginx_container_image_source }}"
force_source: >-2
{{ nginx_container_image_force_source
| default(nginx_container_image_tag | default(false, true)) }}
register: nginx_container_image_info
until: nginx_container_image_info is success
retries: 5
delay: 3
- name: Ensure docker container '{{ nginx_container_name }}' is {{ nginx_container_state }}
community.docker.docker_container:
name: "{{ nginx_container_name }}"
image: "{{ nginx_container_image_reference }}"
env: "{{ nginx_container_env | default(omit, true) }}"
user: "{{ nginx_container_user | default(omit, true) }}"
ports: "{{ nginx_container_ports | default(omit, true) }}"
labels: "{{ nginx_container_labels | default(omit, true) }}"
volumes: "{{ nginx_container_volumes | default(omit, true) }}"
etc_hosts: "{{ nginx_container_etc_hosts | default(omit, true) }}"
networks: "{{ nginx_container_networks | default(omit, true) }}"
purge_networks: "{{ nginx_container_purge_networks | default(omit, true) }}"
restart_policy: "{{ nginx_container_restart_policy }}"
state: "{{ nginx_container_state }}"

View File

@ -0,0 +1,27 @@
---
- name: Ensure container image '{{ nginx_container_image_reference }}' is {{ nginx_state }}
containers.podman.podman_image:
name: "{{ nginx_container_image_reference }}"
state: "{{ nginx_state }}"
pull: "{{ nginx_container_image_source == 'pull' }}"
force: >-2
{{ nginx_container_image_force_source
| default(nginx_container_image_tag | default(false, true)) }}
register: nginx_container_image_info
until: nginx_container_image_info is success
retries: 5
delay: 3
- name: Ensure container '{{ nginx_container_name }}' is {{ nginx_container_state }}
containers.podman.podman_container:
name: "{{ nginx_container_name }}"
image: "{{ nginx_container_image_reference }}"
env: "{{ nginx_container_env | default(omit, true) }}"
user: "{{ nginx_container_user | default(omit, true) }}"
ports: "{{ nginx_container_ports | default(omit, true) }}"
labels: "{{ nginx_container_labels | default(omit, true) }}"
volumes: "{{ nginx_container_volumes | default(omit, true) }}"
etc_hosts: "{{ nginx_container_etc_hosts | default(omit, true) }}"
network: "{{ nginx_container_networks | default(omit, true) }}"
restart_policy: "{{ nginx_container_restart_policy }}"
state: "{{ nginx_container_state }}"

View File

@ -1,10 +1,30 @@
--- ---
- name: Check if state is supported
ansible.builtin.fail:
msg: >-2
Unsupported state '{{ nginx_state }}'. Supported
states are {{ nginx_states | join(', ') }}.
when: nginx_state not in nginx_states
- name: Ensure base path '{{ nginx_base_path }}' exists - name: Check if deployment_method is supported
ansible.builtin.fail:
msg: >-2
Unsupported state '{{ nginx_deployment_method }}'. Supported
states are {{ nginx_deployment_methods | join(', ') }}.
when: nginx_deployment_method not in nginx_deployment_methods
- name: Ensure nginx config file is {{ nginx_state }}
ansible.builtin.file:
path: "{{ nginx_config_file }}"
state: "{{ nginx_state }}"
when: nginx_state == 'absent'
- name: Ensure base path '{{ nginx_base_path }}' is {{ nginx_state }}
ansible.builtin.file: ansible.builtin.file:
path: "{{ nginx_base_path }}" path: "{{ nginx_base_path }}"
state: directory mode: "0755"
mode: 0755 state: >-2
{{ (nginx_state == 'present') | ternary('directory', 'absent') }}
- name: Ensure nginx config file is templated - name: Ensure nginx config file is templated
ansible.builtin.copy: ansible.builtin.copy:
@ -13,25 +33,8 @@
mode: 0640 mode: 0640
notify: notify:
- restart-nginx - restart-nginx
when: nginx_state == 'present'
- name: Ensure docker container image is present - name: Deploy using {{ nginx_deployment_method }}
community.docker.docker_image: ansible.builtin.include_tasks:
name: "{{ nginx_container_image_reference }}" file: "deploy-{{ nginx_deployment_method }}.yml"
state: present
source: pull
force_source: "{{ nginx_container_image_tag is defined and nginx_container_image_tag | string != '' }}"
- name: Ensure docker container '{{ nginx_container_name }}' is running
community.docker.docker_container:
name: "{{ nginx_container_name }}"
image: "{{ nginx_container_image_reference }}"
env: "{{ nginx_container_env | default(omit, true) }}"
user: "{{ nginx_container_user | default(omit, true) }}"
ports: "{{ nginx_container_ports | default(omit, true) }}"
labels: "{{ nginx_container_labels | default(omit, true) }}"
volumes: "{{ nginx_container_volumes | default(omit, true) }}"
etc_hosts: "{{ nginx_container_etc_hosts | default(omit, true) }}"
networks: "{{ nginx_container_networks | default(omit, true) }}"
purge_networks: "{{ nginx_container_purge_networks | default(omit, true) }}"
restart_policy: "{{ nginx_container_restart_policy }}"
state: started

View File

@ -0,0 +1,7 @@
---
nginx_states:
- present
- absent
nginx_deployment_methods:
- docker
- podman

View File

@ -0,0 +1,25 @@
# `finallycoffee.base.powerdns_tsig_key`
Simple ansible role for ensuring a TSIG key is present in a given PowerDNS-
instance.
## Usage
The usage example below assumes `powerdns` is running in a container named `powerdns` (as supplied to `powerdns_tsig_key_container_name`.
```yaml
- hosts: "{{ target_hosts }}"
become: true
roles:
- role: finallycoffee.base.powerdns_tsig_key
vars:
powerdns_tsig_key_name: "nameofmykey"
powerdns_tsig_key_path: "/var/lib/myapp/tsig.key"
powernds_tsig_key_algo: "hmac-sha512"
powerdns_tsig_key_path_owner: "myappuser"
powerdns_tsig_key_path_group: "myappgroup"
powerdns_tsig_key_container_name: 'powerdns'
```
> [!NOTE]
> Support for non-docker deployments is pending.

View File

@ -10,18 +10,41 @@ restic_backup_stdin_command: ~
restic_backup_stdin_command_filename: ~ restic_backup_stdin_command_filename: ~
restic_policy_keep_all_within: 1d restic_policy_keep_all_within: 1d
restic_policy_keep_hourly: 6 restic_policy_keep_hourly: 12
restic_policy_keep_daily: 2 restic_policy_keep_daily: 7
restic_policy_keep_weekly: 7 restic_policy_keep_weekly: 6
restic_policy_keep_monthly: 4 restic_policy_keep_monthly: 6
restic_policy_keep_yearly: 5
restic_policy_backup_frequency: hourly restic_policy_backup_frequency: hourly
restic_base_environment:
RESTIC_JOBNAME: "{{ restic_job_name | default('unknown') }}"
RESTIC_FORGET_KEEP_WITHIN: "{{ restic_policy_keep_all_within }}"
RESTIC_FORGET_KEEP_HOURLY: "{{ restic_policy_keep_hourly }}"
RESTIC_FORGET_KEEP_DAILY: "{{ restic_policy_keep_daily }}"
RESTIC_FORGET_KEEP_WEEKLY: "{{ restic_policy_keep_weekly }}"
RESTIC_FORGET_KEEP_MONTHLY: "{{ restic_policy_keep_monthly }}"
RESTIC_FORGET_KEEP_YEARLY: "{{ restic_policy_keep_yearly }}"
restic_s3_environment:
AWS_ACCESS_KEY_ID: "{{ restic_s3_key_id }}"
AWS_SECRET_ACCESS_KEY: "{{ restic_s3_access_key }}"
restic_complete_environment: >-
{{
restic_base_environment
| combine((restic_s3_environment
if (restic_s3_key_id and restic_s3_access_key) else {}) | default({}))
| combine(restic_environment | default({}))
}}
restic_policy: restic_policy:
keep_within: "{{ restic_policy_keep_all_within }}" keep_within: "{{ restic_policy_keep_all_within }}"
hourly: "{{ restic_policy_keep_hourly }}" hourly: "{{ restic_policy_keep_hourly }}"
daily: "{{ restic_policy_keep_daily }}" daily: "{{ restic_policy_keep_daily }}"
weekly: "{{ restic_policy_keep_weekly }}" weekly: "{{ restic_policy_keep_weekly }}"
monthly: "{{ restic_policy_keep_monthly }}" monthly: "{{ restic_policy_keep_monthly }}"
yearly: "{{ restic_policy_keep_yearly }}"
frequency: "{{ restic_policy_backup_frequency }}" frequency: "{{ restic_policy_backup_frequency }}"
restic_user: root restic_user: root

View File

@ -9,26 +9,43 @@ SyslogIdentifier={{ restic_systemd_syslog_identifier }}
Environment=RESTIC_REPOSITORY={{ restic_repo_url }} Environment=RESTIC_REPOSITORY={{ restic_repo_url }}
Environment=RESTIC_PASSWORD={{ restic_repo_password }} Environment=RESTIC_PASSWORD={{ restic_repo_password }}
{% if restic_s3_key_id and restic_s3_access_key %} {% for kv in restic_complete_environment | dict2items %}
Environment=AWS_ACCESS_KEY_ID={{ restic_s3_key_id }} Environment={{ kv.key }}={{ kv.value }}
Environment=AWS_SECRET_ACCESS_KEY={{ restic_s3_access_key }} {% endfor %}
{% if restic_init | default(true) %}
ExecStartPre=-/bin/sh -c '/usr/bin/restic snapshots || /usr/bin/restic init'
{% endif %} {% endif %}
{% if restic_unlock_before_backup | default(false) %} {% if restic_unlock_before_backup | default(false) %}
ExecStartPre=-/bin/sh -c '/usr/bin/restic unlock' ExecStartPre=-/bin/sh -c 'sleep 3 && /usr/bin/restic unlock'
{% endif %} {% endif %}
ExecStartPre=-/bin/sh -c '/usr/bin/restic snapshots || /usr/bin/restic init'
{% if restic_backup_pre_hook | default(false) %} {% if restic_backup_pre_hook | default(false) %}
ExecStart=-{{ restic_backup_pre_hook }} ExecStartPre=-{{ restic_backup_pre_hook }}
{% endif %} {% endif %}
{% if restic_backup_stdin_command %} {% if restic_backup_stdin_command %}
ExecStart=/bin/sh -c '{{ restic_backup_stdin_command }} | /usr/bin/restic backup --verbose --stdin --stdin-filename {{ restic_backup_stdin_command_filename }}' ExecStart=/bin/sh -c '{{ restic_backup_stdin_command }} | /usr/bin/restic backup \
--retry-lock {{ restic_retry_lock | default('5m') }} \
--verbose --stdin \
--stdin-filename {{ restic_backup_stdin_command_filename }}'
{% else %} {% else %}
ExecStart=/usr/bin/restic --verbose backup {{ restic_backup_paths | join(' ') }} ExecStart=/opt/restic-backup-directories.sh {{ restic_backup_paths | join(' ') }}
{% endif %}
{% if restic_forget_prune | default(true) %}
ExecStartPost=/usr/bin/restic forget --prune \
--retry-lock {{ restic_retry_lock | default('5m') }} \
--keep-within={{ restic_policy.keep_within }} \
--keep-hourly={{ restic_policy.hourly }} \
--keep-daily={{ restic_policy.daily }} \
--keep-weekly={{ restic_policy.weekly }} \
--keep-monthly={{ restic_policy.monthly }} \
--keep-yearly={{ restic_policy.yearly }}
{% endif %}
{% if restic_list_snapshots | default(true) %}
ExecStartPost=-/usr/bin/restic snapshots --retry-lock {{ restic_retry_lock | default('5m') }}
{% endif %} {% endif %}
ExecStartPost=/usr/bin/restic forget --prune --keep-within={{ restic_policy.keep_within }} --keep-hourly={{ restic_policy.hourly }} --keep-daily={{ restic_policy.daily }} --keep-weekly={{ restic_policy.weekly }} --keep-monthly={{ restic_policy.monthly }}
ExecStartPost=-/usr/bin/restic snapshots
{% if restic_backup_post_hook | default(false) %} {% if restic_backup_post_hook | default(false) %}
ExecStartPost=-{{ restic_backup_post_hook }} ExecStartPost=-{{ restic_backup_post_hook }}
{% endif %} {% endif %}
ExecStartPost=/usr/bin/restic check {% if restic_check | default(true) %}
ExecStartPost=/usr/bin/restic check --retry-lock {{ restic_retry_lock | default('5m') }}
{% endif %}