diff options
| author | Colin Wilk <colin.wilk@tum.de> | 2023-05-22 20:17:27 +0200 |
|---|---|---|
| committer | Colin Wilk <colin.wilk@tum.de> | 2023-05-24 19:40:29 +0200 |
| commit | 1f1f6eeaebc148602085515350eb12829f86c315 (patch) | |
| tree | 46dd4aa80ab9125a3254e2b1a26847f41a9e79d6 | |
| download | ansible-role-borgbackup-1f1f6eeaebc148602085515350eb12829f86c315.tar.gz ansible-role-borgbackup-1f1f6eeaebc148602085515350eb12829f86c315.zip | |
init
Signed-off-by: Colin Wilk <colin.wilk@tum.de>
| -rw-r--r-- | .ansible-lint | 12 | ||||
| -rw-r--r-- | .pre-commit-config.yaml | 22 | ||||
| -rw-r--r-- | LICENSE | 21 | ||||
| -rw-r--r-- | README.md | 158 | ||||
| -rw-r--r-- | defaults/main.yml | 125 | ||||
| -rw-r--r-- | meta/argument_specs.yml | 93 | ||||
| -rw-r--r-- | meta/main.yml | 20 | ||||
| -rw-r--r-- | molecule/.gitignore | 2 | ||||
| -rw-r--r-- | molecule/default/Dockerfile.j2 | 15 | ||||
| -rw-r--r-- | molecule/default/converge.yml | 43 | ||||
| -rw-r--r-- | molecule/default/molecule.yml | 39 | ||||
| -rw-r--r-- | molecule/default/tests/test_manual_backup.py | 57 | ||||
| -rw-r--r-- | tasks/client_setup.yml | 120 | ||||
| -rw-r--r-- | tasks/installation.yml | 21 | ||||
| -rw-r--r-- | tasks/main.yml | 9 | ||||
| -rw-r--r-- | tasks/server_setup.yml | 22 |
16 files changed, 779 insertions, 0 deletions
diff --git a/.ansible-lint b/.ansible-lint new file mode 100644 index 0000000..76a35bf --- /dev/null +++ b/.ansible-lint @@ -0,0 +1,12 @@ +exclude_paths: [] + +use_default_rules: true + +enable_list: + - fqcn-builtins + - yaml + - syntax-check[specific] + - name[missing] + +skip_list: + - "yaml[line-length]" diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..0264f0e --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,22 @@ +default_stages: [commit, push] + +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.0.1 + hooks: + - id: check-added-large-files + - id: check-yaml + - id: trailing-whitespace + - id: double-quote-string-fixer + - id: end-of-file-fixer + + - repo: https://github.com/ansible-community/ansible-lint.git + rev: v6.15.0 + hooks: + - id: ansible-lint + files: \.(yaml|yml)$ + + - repo: https://github.com/markdownlint/markdownlint + rev: v0.12.0 + hooks: + - id: markdownlint @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 Colin Wilk + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..1e9a634 --- /dev/null +++ b/README.md @@ -0,0 +1,158 @@ +Ansible Role: BorgBackup +======================== + +An ansible role that installs and configures a cron task for BorgBackup on a +client and (delegated) server. +This allows you to very simply 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,main +``` + +```yaml +# requirements.yml +- src: https://github.com/kliwniloc/ansible-role-borgbackup + version: master + name: kliwniloc.borgbackup +``` + +Role Variables +-------------- + +For (much) more details see `defaults/main.yml` + +```yaml +################################### Required ################################### +# The borg server host to delegate the server tasks to +borg_server_host: "" + +# The public ssh key of the borg server +borg_server_host_ssh_key: "" + +################################### Optional ################################### +# The borg server host to push backups to as it will be used in the backup job +borg_server_host_url: "{{ borg_server_host }}" + +# The repository name that the borg repository is created +borg_backup_name_format: "{hostname}-{now:%Y-%m-%dT%H:%M:%S}" + +# Location for repositories on the borg server +borg_server_user_home: /opt/borg + +# Name for the repository (unique on borg server) +borg_repo_name: "{{ inventory_hostname }}" + +# Borg backup name format (for cron job) +borg_backup_name_format: "{hostname}-{now:%Y-%m-%dT%H:%M:%S}" + +# Should the repo be append only? +borg_mode_append_only: false + +# What compression to use in the backup? +borg_compression: zstd + +# Directories to include in the backup +borg_included_dirs: [] + +# Directories to exclude in the backup +borg_excluded_dirs: [] + +# Passphrase to use with borg +borg_passphrase: "" + +# Where to store the decryption keys on the local machine +borg_decryption_keys_yaml_path: "{{ inventory_dir }}/decryption_keys.yml" + +# Settings for the backup cron job +borg_cron_time: + minute: 0 + hour: 3 +``` + +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 diff --git a/defaults/main.yml b/defaults/main.yml new file mode 100644 index 0000000..95a8937 --- /dev/null +++ b/defaults/main.yml @@ -0,0 +1,125 @@ +--- +################################################################################ +# Borg Server Host Configuration +################################################################################ + +# This it the host, as specified in your ansible inventory file, that the +# backups will be made to. +# Ansible will delegate borg-server related tasks to that host. +# Currently there is only a single backup host supported per role run. +# --- +# borg_server_host: SETME + +# This is the public key of the ssh server of your borg server. +# It is used for protecting against spoofed borg servers. It is recommended you +# set this variable as a group var in your ansible repository as it is a per +# borg-server configuration. To get this key you can run ssh-keyscan against +# your borg server like this: +# ssh-keyscan -t rsa borg.example.org +# You will need to remove the hostname from the output so that the +# remaining key will look something like this: +# ssh-rsa AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA... +# --- +# borg_server_host_ssh_key: SETME + +# This is the host url that will be used for running borg related commands on +# the borg client. The borg server ssh port needs to be reachable from the borg +# borg client under this host. +# This defaults to the borg_server_host which will work as long as the inventory +# hostnames are globally reachable. +borg_server_host_url: '{{ borg_server_host }}' + +# The home directory of the borg user that is created on the borg server. +# All borg borg client repositories will be saved in this directory on the borg +# server. e.g. /opt/borg/client1 /opt/borg/client2 +borg_server_user_home: /opt/borg + + +################################################################################ +# Borg Repository Configuration +# See: https://borgbackup.readthedocs.io/en/stable/usage/serve.html +################################################################################ + +# The name of the repository (directory) created on the borg-server +# `{{ borg_server_user_home }}/{{ borg_repo_name }}` +# This setting is mostly relevant if you use multiple repositories per +# borg-client in which case you have to set a custom repo names / formats to +# avoid clashes. +borg_repo_name: '{{ inventory_hostname }}' + +# Should the repo be append only? (--append-only) +# This will deny any request to delete data from the backup repository coming +# from the client host. This is so that an attacker would not be able to simply +# delete the backups from a compromised client. +# With this configuration option enabled you won't have the ability to remove +# old backups directly from the client that pushes the backups. +# See https://borgbackup.readthedocs.io/en/stable/usage/notes.html#append-only-mode-forbid-compaction +borg_mode_append_only: false + + +################################################################################ +# Borg Backup Configuration +# See: https://borgbackup.readthedocs.io/en/stable/usage/create.html +################################################################################ + +# This is the name of the backup in the configured repository +# The default here creates a backup with the hostname and the current time in +# the name. It is important to dynamically generate the backup names by using +# the placeholders so that you don't have colliding backup names. +# Most of the time the default option is fine. +# For more information about the borg placeholder see +# https://borgbackup.readthedocs.io/en/stable/usage/help.html#borg-help-placeholders +borg_backup_name_format: "{hostname}-{now:%Y-%m-%dT%H:%M:%S}" + +# Borg has a few compression modes to those from: +# none, lz4, zstd[,L], zlib[,L], lzma[,L], auto,C[,L], obfuscate,SPEC,C[,L]. +# For more information see the borg compression page: `borg help compression` or +# https://borgbackup.readthedocs.io/en/stable/usage/help.html#borg-help-compression +borg_compression: zstd + +# This is a list of files and directories to be backed up in the cron job. +# In case you leave this empty, the role will not create an automatic backup job +borg_included_dirs: [] + +# This is a list of files and directories that you wish to have excluded from +# Your backups. You may need this in case you want to remove a file from a +# folder which you want to have backed up e.g. cache directory in application. +# If you want to backup `/application/data` and `/application/db` +# but not `application/cache` you can add `/application` to `borg_included_dirs` +# and add `application/cache` to `borg_excluded_dirs`. +borg_excluded_dirs: [] + +# By default the role is configured to only use an encryption key with no +# passphrase. This allows it to use the borgs command on the machine without any +# haste. If you wish to enable the borg passphrase you can do so here. Note that +# The passphrase will be stored in plaintext inside the cron job. +# For more information about the borg passphrase see +# https://borgbackup.readthedocs.io/en/stable/quickstart.html#passphrase-notes +borg_passphrase: "" + +# Since borg encrypts the backups on the borg-server you should save the +# encryption keys somewhere to another machine to be able to recover the backup +# without the keys on the backup-client. +# While you need the decryption keys as well as actual access to the borg +# repository to download the backup data, you should still treat the decryption +# keys as rather sensitive information. +# Depending on your use case it may be okay to store them in your git repository. +# If wish to encrypt the decryption keys, you look into third party tools for +# that such as ansible-vault, git-crypt or a completely separate secrets +# management system. +borg_decryption_keys_yaml_path: '{{ inventory_dir }}/decryption_keys.yml' + +# Define the cron values for the automatic backup job as specified in the cron +# module. +# https://docs.ansible.com/ansible/latest/collections/ansible/builtin/cron_module.html +# Values that are not specified are omitted +# borg_cron_time: +# minute: +# hour: +# weekday: +# day: +# month: +# special_time: +borg_cron_time: + minute: 0 + hour: 3 diff --git a/meta/argument_specs.yml b/meta/argument_specs.yml new file mode 100644 index 0000000..97ddd7f --- /dev/null +++ b/meta/argument_specs.yml @@ -0,0 +1,93 @@ +--- +argument_specs: + main: + options: + +################################################################################ +# Required +################################################################################ + borg_server_host: + type: str + required: true + + borg_server_host_ssh_key: + type: str + required: true + +################################################################################ +# Optional +################################################################################ + borg_server_host_url: + type: str + required: false + default: "{{ borg_server_host }}" + + borg_server_user_home: + type: str + required: false + default: /opt/borg + + borg_repo_name: + type: str + required: false + default: "{{ inventory_hostname }}" + + borg_backup_name_format: + type: str + required: false + default: "{hostname}-{now:%Y-%m-%dT%H:%M:%S}" + + borg_mode_append_only: + type: bool + required: false + default: false + + borg_compression: + type: str + required: false + default: zstd + + borg_included_dirs: + type: list + elements: str + required: false + default: [] + + borg_excluded_dirs: + type: list + elements: str + required: false + default: [] + + borg_passphrase: + type: str + required: false + + borg_decryption_keys_yaml_path: + type: str + required: false + + borg_cron_time: + type: dict + required: false + options: + minute: + type: str + required: false + default: 0 + hour: + type: str + required: false + default: 3 + weekday: + type: str + required: false + day: + type: str + required: false + month: + type: str + required: false + special_time: + type: str + required: false diff --git a/meta/main.yml b/meta/main.yml new file mode 100644 index 0000000..7af6e93 --- /dev/null +++ b/meta/main.yml @@ -0,0 +1,20 @@ +--- +dependencies: [] + +galaxy_info: + role_name: borgbackup + standalone: true + author: kliwniloc + description: BorgBackup role for for deploying scheduled backups + license: license (MIT) + min_ansible_version: '2.4' + platforms: + - name: Debian + versions: + - all + - name: Ubuntu + versions: + - all + galaxy_tags: + - borgbackup + - backup diff --git a/molecule/.gitignore b/molecule/.gitignore new file mode 100644 index 0000000..dd2354f --- /dev/null +++ b/molecule/.gitignore @@ -0,0 +1,2 @@ +__pycache__ +decryption_keys.yml diff --git a/molecule/default/Dockerfile.j2 b/molecule/default/Dockerfile.j2 new file mode 100644 index 0000000..091ef00 --- /dev/null +++ b/molecule/default/Dockerfile.j2 @@ -0,0 +1,15 @@ +FROM {{ item.image }} + +# Install dependencies. +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + sudo wget \ + python3-pip python3-dev python3-setuptools python3-wheel python3-apt \ + sed ssh openssh-server \ + && rm -rf /var/lib/apt/lists/* \ + && rm -Rf /usr/share/doc && rm -Rf /usr/share/man \ + && apt-get clean + +RUN mkdir /run/sshd + +ENTRYPOINT ["bash", "-c", "/usr/sbin/sshd && sleep infinity"] diff --git a/molecule/default/converge.yml b/molecule/default/converge.yml new file mode 100644 index 0000000..9c23b5f --- /dev/null +++ b/molecule/default/converge.yml @@ -0,0 +1,43 @@ +--- +- name: Converge + hosts: borg-client + + pre_tasks: + # This would usually be set by the user globally on their ansible + # repository and can be a security risk to do automatically. We will + # however set the variable here in the pre_tasks since it is for testing. + - name: Set borg server openssh key variable + become: true + block: + - name: Fetch ssh_key + ansible.builtin.command: > + ssh-keyscan -t rsa + {{ borg_server_host }} + | sed "s/^[^ ]* //" + register: borg_server_ssh_keyscan + changed_when: false + + - name: Set ssh_key + ansible.builtin.set_fact: + borg_server_host_ssh_key: "{{ borg_server_ssh_keyscan.stdout + | split(' ') + | reject('search', borg_server_host) + | join(' ') }}" + + vars: + borg_server_host: borg-server + borg_server_user_home: /opt/borg + borg_decryption_keys_yaml_path: "{{ playbook_dir }}/decryption_keys.yml" + borg_included_dirs: + - /etc + - /home + borg_excluded_dirs: + - /opt + - /var + - /reee reeee + borg_cron_time: + minute: "*" + hour: "*" + + roles: + - role: kliwniloc.borgbackup diff --git a/molecule/default/molecule.yml b/molecule/default/molecule.yml new file mode 100644 index 0000000..f37c640 --- /dev/null +++ b/molecule/default/molecule.yml @@ -0,0 +1,39 @@ +--- +dependency: + name: galaxy + + +driver: + name: docker + + +platforms: + + - name: borg-client + image: ${MOLECULE_DISTRO_CLIENT:-debian:10} + dockerfile: Dockerfile.j2 + pre_build_image: false + docker_networks: + - name: 'molecule-container-net' + driver_options: + # Setting the mtu size due to issues with docker and VPN + com.docker.network.driver.mtu: 1420 + networks: + - name: 'molecule-container-net' + + - name: borg-server + image: ${MOLECULE_DISTRO_SERVER:-debian:10} + dockerfile: Dockerfile.j2 + pre_build_image: false + networks: + - name: 'molecule-container-net' + + +provisioner: + name: ansible + playbooks: + converge: ${MOLECULE_PLAYBOOK:-converge.yml} + side_effect: ${MOLECULE_PLAYBOOK:-side_effect.yml} + +verifier: + name: testinfra diff --git a/molecule/default/tests/test_manual_backup.py b/molecule/default/tests/test_manual_backup.py new file mode 100644 index 0000000..4aa9f27 --- /dev/null +++ b/molecule/default/tests/test_manual_backup.py @@ -0,0 +1,57 @@ +import pytest + +testinfra_hosts = ['borg-client'] + + +compression_types = [ + 'none', + 'lz4', + 'zstd', + 'zstd,10', + 'zlib', + 'zlib,6', +] + + +"""Creates backups with all possible combinations of compression to the backup +host""" +@pytest.mark.parametrize('compression', compression_types) +def test_backup_push(host, compression): + c = host.run(f'borg create -C "{compression}" borg@borg-server:/opt/borg/borg-client::testinfra-{{now:%S.%f}} /etc') + assert c.rc == 0 + assert c.stdout == '' + assert c.stderr == '' + + +@pytest.mark.parametrize('compression', compression_types) +def test_backup_restore(host, compression): + # Create backup + c = host.run(f'borg create -C "{compression}" borg@borg-server:/opt/borg/borg-client::testinfra-backup-restore-{compression} /var') + assert c.rc == 0 + assert c.stdout == '' + assert c.stderr == '' + + # Restore Backup + c = host.run(f'cd /mnt && borg extract borg@borg-server:/opt/borg/borg-client::testinfra-backup-restore-{compression}') + assert c.rc == 0 + assert c.stdout == '' + assert c.stderr == '' + + # Check if every file exists, content has, and permissions / metadata + c1 = host.run('cd /var && find /var -type f -printf "%P\n" | sort | xargs -i sh -c "echo {}; sha512sum {} | cut -d \' \' -f 1; ls -l {}; echo"') + c2 = host.run('cd /mnt/var && find /var -type f -printf "%P\n" | sort | xargs -i sh -c "echo {}; sha512sum {} | cut -d \' \' -f 1; ls -l {}; echo"') + assert c1.rc == 0 and c2.rc == 0 + assert c1.stderr == '' and c2.stderr == '' + assert c1.stdout == c2.stdout + + # Delete directory extract directory again for future tests + c = host.run('rm -rf /mnt/var') + assert c.rc == 0 + assert c.stdout == '' + assert c.stderr == '' + + # Delete backup + c = host.run(f'borg delete borg@borg-server:/opt/borg/borg-client::testinfra-backup-restore-{compression}') + assert c.rc == 0 + assert c.stdout == '' + assert c.stderr == '' diff --git a/tasks/client_setup.yml b/tasks/client_setup.yml new file mode 100644 index 0000000..fee0b6b --- /dev/null +++ b/tasks/client_setup.yml @@ -0,0 +1,120 @@ +--- +- name: Create SSH Directory + ansible.builtin.file: + path: /root/.ssh + owner: root + group: root + mode: '0640' + state: directory + become: true + +- name: Add borg server to known_hosts + ansible.builtin.known_hosts: + name: "{{ borg_server_host_url }}" + key: "{{ borg_server_host_url }} {{ borg_server_host_ssh_key }}" + path: /root/.ssh/known_hosts + state: present + become: true + +- name: Generate SSH keys + community.crypto.openssh_keypair: + path: /root/.ssh/id_rsa + owner: root + group: root + mode: '0600' + comment: "root@{{ inventory_hostname }}" + become: true + register: ssh_key + +- name: Deploy Keys to Borg server + ansible.builtin.lineinfile: + path: "{{ borg_server_user_home }}/.ssh/authorized_keys" + line: > + restrict,command="borg serve + {{ "--append-only" if borg_mode_append_only }} + --restrict-to-repository {{ borg_repo_name }}" + {{ ssh_key.public_key }} root@{{ inventory_hostname }} + search_string: "{{ ssh_key.public_key }}" + state: present + become: true + delegate_to: "{{ borg_server_host }}" + +- name: Initialise Borg repository + ansible.builtin.command: > + borg init --encryption=repokey + borg@{{ borg_server_host_url }}:{{ borg_server_user_home }}/{{ borg_repo_name }} + environment: + BORG_PASSPHRASE: "{{ borg_passphrase }}" + become: true + register: init_borg_output + changed_when: init_borg_output.rc != 2 + failed_when: > + init_borg_output.rc != 2 and + init_borg_output.rc != 0 + +- name: Make sure key file exists + ansible.builtin.file: + path: "{{ borg_decryption_keys_yaml_path }}" + state: touch + mode: '0600' + access_time: preserve + modification_time: preserve + delegate_to: localhost + become: false + +- name: Read Vars file + ansible.builtin.include_vars: + file: "{{ borg_decryption_keys_yaml_path }}" + register: local + +- name: Add repository encryption keys to ansible repo + when: not inventory_hostname in local.ansible_facts + throttle: 1 + block: + - name: If host new read encryption keys + ansible.builtin.command: > + borg key export --paper + borg@{{ borg_server_host_url }}:{{ borg_server_user_home }}/{{ borg_repo_name }} + become: true + register: borg_keys + changed_when: borg_keys.rc != 0 + + - name: If host new add encryption keys to vars + ansible.builtin.set_fact: + decryption_keys: "{{ local.ansible_facts | combine({inventory_hostname: borg_keys.stdout}) }}" + +- name: Update encryption vars + ansible.builtin.copy: + content: "{{ decryption_keys | to_nice_yaml(indent=2, width=2048) }}" + dest: "{{ borg_decryption_keys_yaml_path }}" + mode: '0600' + when: decryption_keys is defined + delegate_to: localhost + become: false + +- name: Set up env for cron job + ansible.builtin.cron: + name: BORG_PASSPHRASE + job: "{{ borg_passphrase }}" + state: "{{ 'present' if (borg_included_dirs | length > 0) else 'absent' }}" + env: true + user: root + become: true + +- name: Set up backup cron jobs + ansible.builtin.cron: + name: BORG (Application level backups) + job: > + borg create -C {{ borg_compression }} + borg@{{ borg_server_host_url }}:{{ borg_server_user_home }}/{{ borg_repo_name }}::{{ borg_backup_name_format }} + {{ borg_included_dirs | map('quote') | join(' ') }} + {% for e in (borg_excluded_dirs | map('quote')) %} --exclude {{ e }} {% endfor %} + user: root + state: "{{ 'present' if (borg_included_dirs | length > 0) else 'absent' }}" + minute: "{{ borg_cron_time.minute | default(omit) }}" + hour: "{{ borg_cron_time.hour | default(omit) }}" + weekday: "{{ borg_cron_time.weekday | default(omit) }}" + day: "{{ borg_cron_time.day | default(omit) }}" + month: "{{ borg_cron_time.month | default(omit) }}" + special_time: "{{ borg_cron_time.special_time | default(omit) }}" + become: true diff --git a/tasks/installation.yml b/tasks/installation.yml new file mode 100644 index 0000000..af379e6 --- /dev/null +++ b/tasks/installation.yml @@ -0,0 +1,21 @@ +--- +- name: Install Debian Server dependencies + ansible.builtin.apt: + name: + - borgbackup + state: present + update_cache: true + become: true + when: ansible_facts['os_family'] == "Debian" + delegate_to: "{{ borg_server_host }}" + +- name: Install Debian Client dependencies + ansible.builtin.apt: + name: + - borgbackup + - cron + - ssh + state: present + update_cache: true + become: true + when: ansible_facts['os_family'] == "Debian" diff --git a/tasks/main.yml b/tasks/main.yml new file mode 100644 index 0000000..7ffef06 --- /dev/null +++ b/tasks/main.yml @@ -0,0 +1,9 @@ +--- +- name: Install dependencies + ansible.builtin.include_tasks: installation.yml + +- name: Run setup on server + ansible.builtin.include_tasks: server_setup.yml + +- name: Run setup on client + ansible.builtin.include_tasks: client_setup.yml diff --git a/tasks/server_setup.yml b/tasks/server_setup.yml new file mode 100644 index 0000000..6b16e29 --- /dev/null +++ b/tasks/server_setup.yml @@ -0,0 +1,22 @@ +--- +- name: Create borg user + ansible.builtin.user: + name: borg + comment: Borgbackup user + create_home: true + home: "{{ borg_server_user_home }}" + generate_ssh_key: true + become: true + delegate_to: "{{ borg_server_host }}" + +- name: Make sure authorized keys exists + ansible.builtin.file: + path: "{{ borg_server_user_home }}/.ssh/authorized_keys" + state: touch + owner: borg + group: borg + mode: '644' + access_time: preserve + modification_time: preserve + become: true + delegate_to: "{{ borg_server_host }}" |