--- # tasks file for chatton.docker_backup # https://docs.ansible.com/ansible/latest/collections/community/docker/docker_container_module.html#ansible-collections-community-docker-docker-container-module # https://docs.docker.com/storage/volumes/#backup-restore-or-migrate-data-volumes - name: Get container details docker_container_info: name: "{{ container_restore }}" register: result - name: Fail if container is not present fail: msg: Cannot restore volumes for a container when it does not exist. Ensure the container exists and try again. when: result.exists == false - debug: msg="{{ result }}" - name: Extract only the volume mounts (not bind mounts) set_fact: volume_mounts="{{ result.container.Mounts | selectattr("Type", "equalto", "volume")}}" - debug: msg="{{ volume_mounts }}" - name: Find relevant volume(s) in S3 amazon.aws.aws_s3: bucket: "{{ aws_s3.bucket }}" mode: list region: "{{ aws_s3.region }}" s3_url: "https://{{ aws_s3.s3_url }}" prefix: "{{ item.Name }}/{{ item.Name }}" aws_access_key: "{{ aws_s3.aws_access_key }}" aws_secret_key: "{{ aws_s3.aws_secret_key }}" register: s3_list_output with_items: "{{ volume_mounts }}" - debug: msg="{{ s3_list_output }}" - name: Extract s3 keys for container set_fact: container_s3_keys="{{ container_s3_keys | default([]) + [item.s3_keys | last] }}" with_items: "{{ s3_list_output.results }}" - debug: msg="{{ container_s3_keys }}" - name: Create a directory for temporary backups if they do not exist ansible.builtin.file: path: "/tmp/{{ item.Name }}" state: directory mode: '0755' with_items: "{{ volume_mounts }}" - name: Download archives from S3 amazon.aws.aws_s3: bucket: "{{ aws_s3.bucket }}" object: "{{ item }}" aws_access_key: "{{ aws_s3.aws_access_key }}" aws_secret_key: "{{ aws_s3.aws_secret_key }}" region: "{{ aws_s3.region }}" s3_url: "https://{{ aws_s3.s3_url }}" mode: get dest: "/tmp/{{ item }}" with_items: "{{ container_s3_keys }}" register: get_out - debug: msg="{{ get_out }}" - set_fact: volume_details: "{{ volume_details | default([]) + [ {'mount': item.0, 's3_key': item.1} ] }}" with_together: - "{{ volume_mounts }}" - "{{ container_s3_keys }}" - debug: msg="{{ volume_details }}" - name: Stop a container community.docker.docker_container: name: "{{ container_restore }}" state: stopped - name: Ensure Volume docker_volume: name: "{{ item.mount.Name }}" state: present with_items: "{{ volume_details }}" - name: Remove contents of volumes community.docker.docker_container: name: "restore-container-{{ item.mount.Name }}-{{ 10 | random }}" image: ubuntu command: "rm -rf ./* " auto_remove: true detach: false # block until this container exists. state: started # start inside the directory we want to wipe working_dir: "{{ item.mount.Destination }}" volumes: - /tmp:/tmp volumes_from: - "{{ container_restore }}" with_items: "{{ volume_details }}" - name: Restore contents of volumes community.docker.docker_container: name: "restore-container-{{ item.mount.Name }}-{{ 10 | random }}" image: ubuntu # extract the tar into the volume. command: "tar xvf /tmp/{{ item.s3_key }}" auto_remove: true detach: false # block until this container exists. state: started # the compressed volume contains the directories, so we start from the root working_dir: "/" volumes: - /tmp:/tmp volumes_from: - "{{ container_restore }}" with_items: "{{ volume_details }}" - name: Start a container community.docker.docker_container: name: "{{ container_restore }}" state: started