--- # This ansible-playbook prepares hosts for use of borg backup # # What it does: # - enable borg ppa # - install borg client # - create SSH key for passwordless login # - generate passphrase for borgi (/root/backup/.borg_passphrase) # - add SSH key at remote storagebox authorized_keys # - create borg dirs (log, root/backup) # - create scripts in /root/backup/ for borg handling # - initialize backup repo on remote machine(s) running borg-init.sh # - install CRON jobs for regular backups # - download generated keyfiles/passwords to local machine (borg-creds/) # ## # # This playbook will normally be run like this: # # ansible-playbook -b -i h8.waeup.org, --ask-vault-pass playbook-install-borg.yml # # Cf.: https://github.com/noplanman/ansible-role-borgbackup/blob/master/tasks/borg-client.yml # ## # # PLEASE NOTE: this playbook requires a gazillion parameters to be set via host vars. # As some of these are hopefully encrypted, you also need the respective # passwords. # ## - hosts: all become: yes vars: tasks: - name: "Activate borg PPA" apt_repository: repo: "ppa:costamagnagianfranco/borgbackup" codename: "{{ ansible_distribution_release }}" state: present - name: "Install packages for borg backup" apt: name: ['borgbackup', 'pwgen', 'sshpass'] state: present - name: "Generate ssh-key for backup." openssh_keypair: path: "/root/.ssh/id_backup" type: "ed25519" register: sshkey - name: "Create directories for config and logs." file: path: '{{ item.path }}' state: directory owner: root group: root mode: '{{ item.mode }}' loop: - { path: '/root/backup', mode: '0700' } - { path: '/var/log/borg', mode: '0755' } - name: "Generate a backup password." shell: cmd: echo 'export BORG_PASSPHRASE="'$(pwgen -s -1 64)'"' > "/root/backup/.borg_passphrase" creates: "/root/backup/.borg_passphrase" - name: "Fix file permissions of password." file: path: '/root/backup/.borg_passphrase' owner: root group: root mode: '0600' - name: "Get authorized_keys from backup server" shell: cmd: > SSHPASS={{ item.password }} sshpass -e scp -o BatchMode=no -o StrictHostKeyChecking=no {{ item.user }}@{{ item.fqdn }}:.ssh/authorized_keys /tmp/authkeys-{{ item.type }}-{{ item.fqdn }}-authkeys when: item.type in ['hetzner',] with_items: "{{ borgbackup_servers }}" changed_when: false failed_when: false - name: "update authorized_keys" authorized_key: user: "root" key: "{{ sshkey.public_key }}" path: /tmp/authkeys-{{ item.type }}-{{ item.fqdn }}-authkeys manage_dir: false when: item.type in ['hetzner', ] with_items: "{{ borgbackup_servers }}" register: authkeys - name: "Upload changed authorized_keys" shell: cmd: | SSHPASS={{ item.password }} sshpass -e sftp -oBatchMode=no -oStrictHostKeyChecking=no {{ item.user }}@{{ item.fqdn }} << EOF mkdir ./.ssh chmod 0700 ./.ssh cd .ssh put /tmp/authkeys-{{ item.type }}-{{ item.fqdn }}-authkeys authorized_keys chmod 0600 authorized_keys bye EOF when: (item.type in ['hetzner', ]) and (authkeys.changed) with_items: "{{ borgbackup_servers }}" - name: "Remove tmp authorized_keys files" file: path: /tmp/authkeys-{{ item.type }}-{{ item.fqdn }}-authkeys state: absent with_items: "{{ borgbackup_servers }}" - name: "Disable strict host key checks for backup server" blockinfile: dest: "/root/.ssh/config" create: true marker: "### {mark} ANSIBLE MANAGED BLOCK {{ item.fqdn }} ###" content: | Host {{ item.fqdn }} StrictHostKeyChecking no IdentityFile /root/.ssh/id_backup {% if item.port is defined %}Port {{ item.port }}{% endif %} with_items: "{{ borgbackup_servers }}" - name: "Upload borg-init.sh script" template: src: "borg-init.sh.j2" dest: "/root/backup/borg-init.sh" owner: "root" group: "root" mode: "0744" force: no - name: "Upload borg-backup.sh script" template: src: "borg-backup.sh.j2" dest: "/root/backup/borg-backup.sh" owner: "root" group: "root" mode: "0700" force: no - name: "Upload sb-ftp.sh script" template: src: "sb-ftp.sh.j2" dest: "/root/backup/sb-ftp.sh" owner: "root" group: "root" mode: "0700" force: no - name: "Create env scripts" template: src: "borg-env.sh.j2" dest: "/root/backup/env-{{ item.fqdn }}.sh" owner: "root" group: "root" mode: "0600" force: no with_items: "{{ borgbackup_servers }}" - name: "Create borg README on server" template: src: "borg-README.txt.j2" dest: "/root/backup/README-borg.txt" owner: "root" group: "root" mode: "0600" force: no - name: "Initialize repo" command: /root/backup/borg-init.sh args: creates: /root/.config/borg/keys/ - name: "Create backup cronjob" cron: cron_file: "borg-backup" user: "root" name: "borg-backup" minute: "{{ borgbackup_cron_minute }}" hour: "{{ borgbackup_cron_hour }}" day: "{{ borgbackup_cron_day }}" job: "/root/backup/borg-backup.sh > /dev/null 2>&1" - name: "Fetch keyfiles to localhost" fetch: src: /root/.config/borg/keys/{{ item.fqdn | replace('.', '_') | replace('-', '_') }}__{{ item.home }}{{ item.pool }}_{{ inventory_hostname_short }} dest: borg-creds/ flat: yes with_items: "{{ borgbackup_servers }}" - name: "Fetch passwordfile to localhost" fetch: src: /root/backup/.borg_passphrase dest: borg-creds/_borg_passphrase-{{ inventory_hostname_short }} flat: yes - debug: msg: - "A copy of the keyfile and the borg password were saved to the" - "local borg-creds/ directory." - "Please keep them in a safe place, away from the backup machine" - "and the backuped machine. You might want to encrypt them."