--- - name: Gather system facts (hardware) ansible.builtin.setup: gather_subset: - hardware become: true - name: Set backup kopia repository server when: node['name'] == "bk" block: - name: Download kopia deb file (x86_64) ansible.builtin.get_url: url: "https://github.com/kopia/kopia/releases/download/v{{ version['packages']['kopia'] }}/\ kopia_{{ version['packages']['kopia'] }}_linux_amd64.deb" dest: "/var/cache/apt/archives/kopia-{{ version['packages']['kopia'] }}.deb" owner: "root" group: "root" mode: "0644" become: true when: ansible_facts['architecture'] == "x86_64" - name: Download kopia deb file (aarch64) ansible.builtin.get_url: url: "https://github.com/kopia/kopia/releases/download/v{{ version['packages']['kopia'] }}/\ kopia_{{ version['packages']['kopia'] }}_linux_arm64.deb" dest: "/var/cache/apt/archives/kopia-{{ version['packages']['kopia'] }}.deb" owner: "root" group: "root" mode: "0644" become: true when: ansible_facts['architecture'] == "aarch64" - name: Create kopia directory ansible.builtin.file: path: "{{ item.name }}" state: "directory" owner: "{{ ansible_user }}" group: "root" mode: "{{ item.mode }}" loop: - name: "/etc/kopia" mode: "0700" - name: "/etc/kopia/ssl" mode: "0700" - name: "/var/cache/kopia" mode: "0700" become: true no_log: true - name: Install kopia ansible.builtin.apt: deb: "/var/cache/apt/archives/kopia-{{ version['packages']['kopia'] }}.deb" state: "present" become: true - name: Deploy kopia env ansible.builtin.template: src: "{{ hostvars['console']['node']['config_path'] }}/services/systemd/common/kopia/kopia.env.j2" dest: "/etc/secrets/{{ node['uid'] }}/kopia.env" owner: "{{ ansible_user }}" group: "root" mode: "0400" become: true notify: "notification_restart_kopia_server" no_log: true - name: Deploy kopia certificate and key ansible.builtin.copy: content: | {{ item.value }} dest: "/etc/kopia/ssl/{{ item.name }}" owner: "{{ ansible_user }}" group: "{{ node['group'] }}" mode: "{{ item.mode }}" loop: - name: "kopia.crt" value: | {{ hostvars['console']['kopia']['crt'] | trim }} {{ hostvars['console']['ca']['intermediate']['crt'] }} mode: "0440" - name: "kopia.key" value: "{{ hostvars['console']['kopia']['key'] }}" mode: "0400" notify: "notification_restart_kopia_server" no_log: true - name: Check repository existance ansible.builtin.stat: path: "{{ node['home_path'] }}/data/kopia/repository" register: "is_kopia_repository" - name: Create repository directory ansible.builtin.file: path: "{{ node['home_path'] }}/data/kopia/repository" state: "directory" owner: "{{ ansible_user }}" group: "{{ node['group'] }}" mode: "0770" when: not is_kopia_repository.stat.exists - name: Create kopia repository ansible.builtin.shell: | set -a . /etc/secrets/{{ node['uid'] }}/kopia.env set +a /usr/bin/kopia repository create filesystem \ --path="{{ node['home_path'] }}/data/kopia/repository" \ --description="ilnmors.internal kopia repository" \ --create-only when: not is_kopia_repository.stat.exists changed_when: true register: "is_repository_created" no_log: true - name: Connect to kopia repository ansible.builtin.shell: | set -a . /etc/secrets/{{ node['uid'] }}/kopia.env set +a /usr/bin/kopia repository connect filesystem \ --path="{{ node['home_path'] }}/data/kopia/repository" \ --override-username="il" \ --override-hostname="{{ node['name'] }}.{{ domain['internal'] }}" when: - not is_kopia_repository.stat.exists - is_repository_created.rc == 0 changed_when: true register: "is_repository_connected" no_log: true - name: Create kopia user ansible.builtin.shell: | set -a . /etc/secrets/{{ node['uid'] }}/kopia.env set +a /usr/bin/kopia server users add \ --user-password {{ item.password | quote }} \ {{ item.name }} loop: - name: "console@console.ilnmors.internal" password: "{{ hostvars['console']['kopia']['users']['console'] }}" - name: "infra@infra.ilnmors.internal" password: "{{ hostvars['console']['kopia']['users']['infra'] }}" - name: "app@app.ilnmors.internal" password: "{{ hostvars['console']['kopia']['users']['app'] }}" when: - not is_kopia_repository.stat.exists - is_repository_connected.rc == 0 changed_when: true register: "is_user_created" no_log: true - name: Set kopia console ACL ansible.builtin.shell: | set -a . /etc/secrets/{{ node['uid'] }}/kopia.env set +a /usr/bin/kopia server acl add \ --user console@console.ilnmors.internal \ --target {{ item }} \ --access FULL loop: - "type=snapshot" - "type=policy" - "type=user" - "type=acl" - "type=content" when: - not is_kopia_repository.stat.exists - is_repository_connected.rc == 0 changed_when: true no_log: true - name: Set kopia infra ACL ansible.builtin.shell: | set -a . /etc/secrets/{{ node['uid'] }}/kopia.env set +a /usr/bin/kopia server acl add \ --user infra@infra.ilnmors.internal \ --target {{ item.target }} \ --access {{ item.access }} loop: - target: "type=snapshot" access: "FULL" - target: "type=policy" access: "READ" - target: "type=policy,username=infra,hostname=infra.ilnmors.internal" access: "FULL" - target: "type=content" access: "APPEND" when: - not is_kopia_repository.stat.exists - is_repository_connected.rc == 0 changed_when: true no_log: true - name: Set kopia app ACL ansible.builtin.shell: | set -a . /etc/secrets/{{ node['uid'] }}/kopia.env set +a /usr/bin/kopia server acl add \ --user app@app.ilnmors.internal \ --target {{ item.target }} \ --access {{ item.access }} loop: - target: "type=snapshot" access: "FULL" - target: "type=policy" access: "READ" - target: "type=policy,username=app,hostname=app.ilnmors.internal" access: "FULL" - target: "type=content" access: "APPEND" when: - not is_kopia_repository.stat.exists - is_repository_connected.rc == 0 changed_when: true no_log: true - name: Set kopia policy ansible.builtin.shell: | set -a . /etc/secrets/{{ node['uid'] }}/kopia.env set +a /usr/bin/kopia policy set \ {{ item.content }} loop: - content: | --global \ --compression=zstd - content: | infra@infra.ilnmors.internal \ --compression=zstd \ --keep-latest=10 \ --keep-hourly=0 \ --keep-daily=14 \ --keep-weekly=4 \ --keep-monthly=6 \ --keep-annual=1 - content: | app@app.ilnmors.internal \ --compression=none \ --keep-latest=10 \ --keep-hourly=0 \ --keep-daily=14 \ --keep-weekly=4 \ --keep-monthly=6 \ --keep-annual=1 when: - not is_kopia_repository.stat.exists - is_repository_connected.rc == 0 changed_when: true no_log: true - name: Set kopia parameters ansible.builtin.shell: | set -a . /etc/secrets/{{ node['uid'] }}/kopia.env set +a /usr/bin/kopia repository set-parameters \ --max-pack-size-mb=100 when: - not is_kopia_repository.stat.exists - is_repository_connected.rc == 0 changed_when: true no_log: true - name: Deploy kopia server service file ansible.builtin.template: src: "{{ hostvars['console']['node']['config_path'] }}/services/systemd/common/kopia/kopia-server.service.j2" dest: "{{ node['home_path'] }}/.config/systemd/user/kopia-server.service" owner: "{{ ansible_user }}" group: "{{ node['group'] }}" mode: "0644" validate: "/usr/bin/systemd-analyze verify %s" become: true notify: "notification_restart_kopia_server" - name: Enable kopia server service ansible.builtin.systemd: name: "kopia-server.service" state: "started" enabled: true scope: "user" daemon_reload: true - name: Set infra/app backup kopia when: node['name'] in ["infra", "app"] block: - name: Set kopia uid ansible.builtin.set_fact: kopia_uid: 951 - name: Download kopia deb file (x86_64) ansible.builtin.get_url: url: "https://github.com/kopia/kopia/releases/download/v{{ version['packages']['kopia'] }}/\ kopia_{{ version['packages']['kopia'] }}_linux_amd64.deb" dest: "/var/cache/apt/archives/kopia-{{ version['packages']['kopia'] }}.deb" owner: "root" group: "root" mode: "0644" become: true when: ansible_facts['architecture'] == "x86_64" - name: Download kopia deb file (aarch64) ansible.builtin.get_url: url: "https://github.com/kopia/kopia/releases/download/v{{ version['packages']['kopia'] }}/\ kopia_{{ version['packages']['kopia'] }}_linux_arm64.deb" dest: "/var/cache/apt/archives/kopia-{{ version['packages']['kopia'] }}.deb" owner: "root" group: "root" mode: "0644" become: true when: ansible_facts['architecture'] == "aarch64" - name: Create kopia group ansible.builtin.group: name: "kopia" gid: "{{ kopia_uid }}" state: "present" become: true - name: Create kopia user ansible.builtin.user: name: "kopia" uid: "{{ kopia_uid }}" group: "kopia" shell: "/usr/sbin/nologin" password_lock: true comment: "Kopia backup User" state: "present" become: true - name: Create kopia directory ansible.builtin.file: path: "{{ item.name }}" state: "directory" owner: "kopia" group: "root" mode: "{{ item.mode }}" loop: - name: "/etc/kopia" mode: "0700" - name: "/etc/secrets/951" mode: "0500" - name: "/var/cache/kopia" mode: "0700" become: true no_log: true - name: Install kopia ansible.builtin.apt: deb: "/var/cache/apt/archives/kopia-{{ version['packages']['kopia'] }}.deb" state: "present" become: true - name: Deploy kopia env ansible.builtin.template: src: "{{ hostvars['console']['node']['config_path'] }}/services/systemd/common/kopia/kopia.env.j2" dest: "/etc/secrets/{{ kopia_uid }}/kopia.env" owner: "{{ kopia_uid }}" group: "root" mode: "0400" become: true no_log: true - name: Check data directory existance ansible.builtin.stat: path: "{{ node['home_path'] }}/data/" register: "is_data_dir" - name: Delete lost+found directory on data directory ansible.builtin.file: path: "{{ node['home_path'] }}/data/lost+found/" state: "absent" become: true when: is_data_dir.stat.exists - name: Check data directory empty ansible.builtin.find: path: "{{ node['home_path'] }}/data/" file_type: "any" hidden: true recurse: false register: "is_data_dir_empty" when: is_data_dir.stat.exists - name: Connect kopia server environment: KOPIA_PASSWORD: "{{ hostvars['console']['kopia']['users'][node['name']] }}" ansible.builtin.shell: | /usr/bin/kopia repository connect server \ --url=https://{{ services['kopia']['domain']['internal'] }}.{{ domain['internal'] }}:443 \ --override-username={{ node['name'] }} \ --override-hostname={{ node['name'] }}.{{ domain['internal'] }} become: true when: (is_data_dir_empty.matched | default(1)) == 0 changed_when: false failed_when: is_kopia_connected.rc != 0 register: "is_kopia_connected" no_log: true - name: Check whether Kopia snapshot exists environment: KOPIA_PASSWORD: "{{ hostvars['console']['kopia']['users'][node['name']] }}" ansible.builtin.shell: | /usr/bin/kopia snapshot list \ {{ node['name'] }}@{{ node['name'] }}.{{ domain['internal'] }}:{{ node['home_path'] }}/data \ --json \ --max-results=1 become: true when: (is_kopia_connected.rc | default(1)) == 0 changed_when: false failed_when: false register: "is_snapshot_exist" no_log: true - name: Restore data directory environment: KOPIA_PASSWORD: "{{ hostvars['console']['kopia']['users'][node['name']] }}" ansible.builtin.shell: | /usr/bin/kopia snapshot restore \ --snapshot-time=latest \ {{ node['name'] }}@{{ node['name'] }}.{{ domain['internal'] }}:{{ node['home_path'] }}/data \ {{ node['home_path'] }}/data become: true when: - (is_data_dir_empty.matched | default(1)) == 0 - (is_kopia_connected.rc | default(1)) == 0 - (is_snapshot_exist.stdout | default('[]', true) | from_json | list | length ) > 0 changed_when: is_kopia_restored.rc == 0 failed_when: is_kopia_restored.rc != 0 register: "is_kopia_restored" no_log: true - name: Disconnect kopia server ansible.builtin.shell: | /usr/bin/kopia repository disconnect become: true when: - (is_data_dir_empty.matched | default(1)) == 0 - (is_kopia_connected.rc | default(1)) == 0 changed_when: false failed_when: false no_log: true - name: Deploy kopia backup service files ansible.builtin.template: src: "{{ hostvars['console']['node']['config_path'] }}/services/systemd/common/kopia/{{ item }}.j2" dest: "/etc/systemd/system/{{ item }}" owner: "root" group: "root" mode: "0644" validate: "/usr/bin/systemd-analyze verify %s" loop: - "kopia-backup.service" - "kopia-backup.timer" become: true - name: Enable Kopia backup timer ansible.builtin.systemd: name: "kopia-backup.timer" state: "started" enabled: true daemon_reload: true become: true - name: Set console kopia when: node['name'] == "console" block: - name: Download kopia ansible.builtin.get_url: url: "https://github.com/kopia/kopia/releases/download/v{{ version['packages']['kopia'] }}/\ kopia_{{ version['packages']['kopia'] }}_linux_{{ item }}.deb" dest: "{{ node['data_path'] }}/bin/kopia-{{ version['packages']['kopia'] }}-{{ item }}.deb" owner: "{{ ansible_user }}" group: "{{ node['group'] }}" mode: "0600" loop: - "amd64" - "arm64" - name: Install kopia (x86_64) ansible.builtin.apt: deb: "{{ node['data_path'] }}/bin/kopia-{{ version['packages']['kopia'] }}-amd64.deb" state: "present" become: true when: ansible_facts['architecture'] == "x86_64" - name: Install kopia (aarch64) ansible.builtin.apt: deb: "{{ node['data_path'] }}/bin/kopia-{{ version['packages']['kopia'] }}-arm64.deb" state: "present" become: true when: ansible_facts['architecture'] == "aarch64" - name: Connect console kopia server environment: KOPIA_PASSWORD: "{{ hostvars['console']['kopia']['users']['console'] }}" ansible.builtin.shell: | /usr/bin/kopia repository connect server \ --url=https://{{ services['kopia']['domain']['internal'] }}.{{ domain['internal'] }}:443 \ --override-username={{ node['name'] }} \ --override-hostname={{ node['name'] }}.{{ domain['internal'] }} changed_when: false failed_when: is_kopia_connected.rc != 0 register: "is_kopia_connected" no_log: true