diff --git a/roles/restic/defaults/main.yaml b/roles/restic/defaults/main.yaml new file mode 100644 index 0000000..e251128 --- /dev/null +++ b/roles/restic/defaults/main.yaml @@ -0,0 +1,15 @@ +--- +restic_service_name: restic.service +restic_service_state: started +restic_service_enabled: yes + +restic_arch: amd64 +restic_version: 0.9.6 +restic_url: "https://github.com/restic/restic/releases/download/v{{ restic_version }}/restic_{{ restic_version }}_linux_{{ restic_arch }}.bz2" +restic_checksum: sha256:a88ca09d1dd051d470965667a224a2b81930c6628a0566b7b17868be40207dc8 +restic_bin_path: /usr/local/bin +restic_etc_path: /etc/restic +restic_path: "{{ restic_bin_path }}/restic" + +restic_repos: [] +restic_jobs: [] diff --git a/roles/restic/tasks/default.yaml b/roles/restic/tasks/default.yaml new file mode 100644 index 0000000..e69de29 diff --git a/roles/restic/tasks/job.yaml b/roles/restic/tasks/job.yaml new file mode 100644 index 0000000..5f076cd --- /dev/null +++ b/roles/restic/tasks/job.yaml @@ -0,0 +1,28 @@ +--- +- name: create job config directory + file: + path: "{{ restic_etc_path }}/jobs/{{ item.name }}" + owner: root + group: root + mode: 0755 + state: directory + +- name: create job exclude file + template: + src: exclude.txt.j2 + dest: "{{ restic_etc_path }}/jobs/{{ item.name }}/exclude.txt" + owner: root + group: root + mode: 0644 + +- name: create cron + cron: + name: "restic {{ item.name }} job" + hour: "{{ item.cron.hour | default(omit) }}" + minute: "{{ item.cron.minute | default(omit) }}" + day: "{{ item.cron.day | default(omit) }}" + month: "{{ item.cron.month | default(omit) }}" + weekday: "{{ item.cron.weekday | default(omit) }}" + user: "{{ item.cron.user | default('root') }}" + state: "{{ item.cron.state | default('present') }}" + job: ". {{ restic_etc_path }}/repos/{{ item.repo }}/env.sh && restic backup -q --exclude-file {{ restic_etc_path }}/jobs/{{ item.name }}/exclude.txt {{ item.paths | join(' ') }}" diff --git a/roles/restic/tasks/main.yaml b/roles/restic/tasks/main.yaml new file mode 100644 index 0000000..a6c5430 --- /dev/null +++ b/roles/restic/tasks/main.yaml @@ -0,0 +1,74 @@ +--- +- name: gather os specific variables + include_vars: "{{ lookup('first_found', possible_files) }}" + vars: + possible_files: + files: + - "{{ ansible_distribution }}-{{ ansible_distribution_version }}.yaml" + - "{{ ansible_distribution }}.yaml" + - "{{ ansible_os_family }}.yaml" + - "default.yaml" + paths: + - vars + +- name: include os specific tasks + include_tasks: "{{ lookup('first_found', possible_files) }}" + vars: + possible_files: + files: + - "{{ ansible_distribution }}-{{ ansible_distribution_version }}.yaml" + - "{{ ansible_distribution }}.yaml" + - "{{ ansible_os_family }}.yaml" + - "default.yaml" + paths: + - tasks + +- name: "download restic {{ restic_version }}" + get_url: + url: "{{ restic_url }}" + checksum: "{{ restic_checksum }}" + dest: "{{ restic_path }}.bz2" + owner: root + group: root + mode: 0400 + register: dl + +- name: determine if restic exists + stat: + path: "{{ restic_path }}" + register: st + +- name: decompress restic + command: + cmd: "bunzip2 -k {{ restic_path }}.bz2" + creates: "{{ restic_path }}" + when: dl.changed or not st.stat.exists + #notify: + # - restart restic + +- name: manage restic attributes + file: + path: "{{ restic_path }}" + owner: root + group: root + mode: 0755 + +- name: create etc tree + file: + path: "{{ item }}" + state: directory + owner: root + group: root + mode: 0755 + loop: + - "{{ restic_etc_path }}" + - "{{ restic_etc_path }}/repos" + - "{{ restic_etc_path }}/jobs" + +- name: manage repos + include: repo.yaml + loop: "{{ restic_repos | default([]) }}" + +- name: manage jobs + include: job.yaml + loop: "{{ restic_jobs | default([]) }}" diff --git a/roles/restic/tasks/repo.yaml b/roles/restic/tasks/repo.yaml new file mode 100644 index 0000000..d63fa47 --- /dev/null +++ b/roles/restic/tasks/repo.yaml @@ -0,0 +1,37 @@ +--- +- name: get repo status + shell: + cmd: restic -q -r {{ item.repo }} snapshots 2> /dev/null + ignore_errors: yes + environment: "{{ item.environment | default({}) }}" + register: restic_init + +- name: init repos + shell: + cmd: restic -q -r {{ item.repo }} init + environment: "{{ item.environment | default({}) }}" + when: restic_init.rc != 0 + +- name: create repo config directory + file: + path: "{{ restic_etc_path }}/repos/{{ item.name }}" + owner: root + group: root + mode: 0755 + state: directory + +- name: create repo env directory + file: + path: "{{ restic_etc_path }}/repos/{{ item.name }}" + owner: root + group: root + mode: 0755 + state: directory + +- name: create repo environment helper + template: + src: env.sh.j2 + dest: "{{ restic_etc_path }}/repos/{{ item.name }}/env.sh" + owner: root + group: root + mode: 0400 diff --git a/roles/restic/templates/env.sh.j2 b/roles/restic/templates/env.sh.j2 new file mode 100644 index 0000000..4cae8cf --- /dev/null +++ b/roles/restic/templates/env.sh.j2 @@ -0,0 +1,6 @@ +#!/bin/bash + +export RESTIC_REPOSITORY="{{ item.repo }}" +{% for k, v in item.environment.items() %} +export {{ k | upper }}="{{ v }}" +{% endfor %} diff --git a/roles/restic/templates/exclude.txt.j2 b/roles/restic/templates/exclude.txt.j2 new file mode 100644 index 0000000..b7962d7 --- /dev/null +++ b/roles/restic/templates/exclude.txt.j2 @@ -0,0 +1,3 @@ +{% for exclude in item.exclude %} +{{ exclude }} +{% endfor %} diff --git a/roles/restic/vars/default.yaml b/roles/restic/vars/default.yaml new file mode 100644 index 0000000..e69de29