- name: parse config set_fact: backup_backend: "{% if backups.mode in ['standalone-restic', 'hypervisor-restic'] %}restic{% else %}False{% endif %}" backup_executor: "{% if backups.mode in ['vm-via-hypervisor'] %}False{% else %}True{% endif %}" - name: create config folder file: path: /etc/backup-client/ state: directory owner: root group: root mode: 0700 - name: setup hosts that actualy run backup code (not vms for example) when: backup_executor block: - name: generate ssh key register: backup_ssh_key_task community.crypto.openssh_keypair: path: /etc/backup-client/id_ed25519 type: ed25519 - name: create retention file copy: dest: /etc/backup-client/retention.env owner: root group: root mode: 0700 content: | export BACKUP_RETENTION_HOURS={{ backups.retention.hours }} export BACKUP_RETENTION_DAYS={{ backups.retention.days }} export BACKUP_RETENTION_WEEKS={{ backups.retention.weeks }} export BACKUP_RETENTION_MONTHS={{ backups.retention.months }} export BACKUP_RETENTION_YEARS={{ backups.retention.years }} - name: copy backup config loop: - name: 'enabled' flag: '{{ backups.enabled }}' file: path: /etc/backup-client/{{ item.name }} owner: root group: root mode: 0600 state: "{% if item.flag %}touch{% else %}absent{% endif %}" - name: copy scripts loop: - backup-retention - backup-standalone - backup-vm - backup-all-vms - backup-full - backup-cronjob - backup-check - backup-export - status-email-root template: src: "{{ item }}.j2" dest: "/usr/local/bin/{{ item }}" owner: root group: root mode: 0755 validate: /bin/bash -n %s - name: copy systemd services notify: - reload systemd loop: - backup-check - backup-retention - backup-run - backup-export - status-email-root@ template: src: "{{ item }}.service.j2" dest: "/etc/systemd/system/{{ item }}.service" owner: root group: root mode: 0644 # validate: /usr/bin/systemd-analyze verify %s - name: copy timers notify: - reload systemd - enable timers loop: - check - retention - run - export template: src: "timer.j2" dest: "/etc/systemd/system/backup-{{ item }}.timer" owner: root group: root mode: 0644 # validate: /usr/bin/systemd-analyze verify %s - name: create data folder file: path: /var/backup-client/ state: directory owner: root group: root mode: 0700 - name: create a remote sftp user if enabled when: - backups.remote_sftp_user.enabled - backup_executor delegate_to: "{{ backups.remote_sftp_user.host }}" block: - name: "create user {{ backups.remote_sftp_user.name }}" user: name: "{{ backups.remote_sftp_user.name }}" createhome: yes shell: /sbin/nologin system: false group: "{{ backups.remote_sftp_user.group }}" groups: "{{ backups.remote_sftp_user.groups }}" - name: add ssh key to user when: not ansible_check_mode ansible.posix.authorized_key: user: "{{ backups.remote_sftp_user.name }}" state: present key: '{{ backup_ssh_key_task.public_key }}' - name: create chroot folder file: path: "{{ backups.remote_sftp_user.chroot_basepath }}" owner: root group: root mode: 0755 state: directory - name: create bind mount point in chroot folder file: path: "{{ backups.remote_sftp_user.chroot_basepath }}/backups" owner: "{{ backups.remote_sftp_user.name }}" group: "{{ backups.remote_sftp_user.group }}" mode: 0700 state: directory - name: create storage folder when: backups.remote_sftp_user.create_storage_folder file: path: "{{ backups.remote_sftp_user.storage_path }}" owner: "{{ backups.remote_sftp_user.name }}" group: "{{ backups.remote_sftp_user.group }}" mode: 0700 state: directory - name: "setup bindmount" loop: - mounted - present mount: path: "{{ backups.remote_sftp_user.chroot_basepath }}/backups" src: "{{ backups.remote_sftp_user.storage_path }}" opts: "rw,bind,noauto,x-systemd.automount" fstype: auto passno: "0" state: "{{ item }}" - name: handle common restic based setup tasks when: - backup_backend == 'restic' - backup_executor block: - name: install backend tools (restic) apt: pkg: - restic - name: copy exclude file copy: dest: /etc/backup-client/exclude_files owner: root group: root mode: 0600 content: "{{ backups.exclude_files|filterEnabled|join('\n') }}" - name: copy include file copy: dest: /etc/backup-client/include_files owner: root group: root mode: 0600 content: "{{ backups.include_files|filterEnabled|join('\n') }}" - name: create repo key for restic shell: "umask 177; dd if=/dev/urandom of=/etc/backup-client/restic.key bs=1k count=16" args: creates: "/etc/backup-client/restic.key" - name: set repo key permissions file: path: /etc/backup-client/restic.key owner: root group: root mode: 0600 - name: create restic env file copy: dest: /etc/backup-client/restic.env owner: root group: root mode: 0700 content: | export RESTIC_REPOSITORY="{{ backups.backends.restic.url }}" export RESTIC_PASSWORD_FILE="/etc/backup-client/restic.key" - name: create restic repository folder when: backups.backends.restic.repo_type == 'local' file: path: "{{ backups.backends.restic.url }}" state: directory owner: root group: root mode: 0700 - name: create repo for restic shell: 'source /etc/backup-client/restic.env; restic snapshots > /dev/null || restic init' args: executable: /bin/bash - name: handle hypervisor mode when: backups.mode == 'hypervisor-restic' block: - name: create vms config folder file: path: /etc/backup-client/vms/ state: directory owner: root group: root mode: 0700 - name: create vm mount point file: path: /var/backup-client/vm-mountpoint/ state: directory owner: root group: root mode: 0700 - name: handle vm-via-hypervisor mode when: backups.mode == 'vm-via-hypervisor' block: - name: create config folder on vm host delegate_to: "{{ vm['host'] }}" file: dest: /etc/backup-client/vms/{{ vm['name'] }} state: directory owner: root group: root mode: 0700 - name: copy exclude file to vm host delegate_to: "{{ vm['host'] }}" copy: dest: /etc/backup-client/vms/{{ vm['name'] }}/exclude_files owner: root group: root mode: 0600 content: "{{ backups.exclude_files|filterEnabled|vmpath2hostpath(mountpoint='/var/backup-client/vm-mountpoint')|join('\n') }}" - name: copy include file to vm host delegate_to: "{{ vm['host'] }}" copy: dest: /etc/backup-client/vms/{{ vm['name'] }}/include_files owner: root group: root mode: 0600 content: "{{ backups.include_files|filterEnabled|vmpath2hostpath(mountpoint='/var/backup-client/vm-mountpoint')|join('\n') }}" - name: copy vm backup config to vm host delegate_to: "{{ vm['host'] }}" loop: - name: 'enabled' flag: '{{ backups.enabled }}' file: path: /etc/backup-client/vms/{{ vm['name'] }}/{{ item.name }} owner: root group: root mode: 0600 state: "{% if item.flag %}touch{% else %}absent{% endif %}"