@guido has demonstrated in his answer how to use the backup_file attribute returned by the copy module. As pointed out in my different comments, this is really handy if:
- you want to restore the file during the same run of ansible
- you store the value somewhere when copying (e.g. a var in memory cache, a db entry, a file on disk...) in one run and retrieve it in a later run to perform your restore action.
Here is an other solution you can use if you don't have that info or you don't want to manage that. For clarity sake, I took the case where you want to restore the latest backup file available on disk. You can perfectly adapt that to meet any other specific requirement.
The basic workflow:
- list all the backup files available on the target disk.
- choose the most recent one.
- copy that file back in place.
Note that although my demo playbook targets localhost, it will work with any target provided the file has backup candidates. I'll let you harden this point your own way and according to your own requirements.
Prior to running my playbook, I created a file and copied it several times with a random content creating backups each time. I used the following playbook to do so:
---
- name: Create some file with backup
hosts: localhost
gather_facts: false
vars:
my_file: /tmp/test_restore/toto.txt
tasks:
- name: copy file
copy:
dest: "{{ my_file }}"
content: "{{ 1000 | random }}"
backup: true
The resulting folder content is as follow:
/tmp/test_restore/
├── toto.txt
├── toto.txt.14644.2020-12-19@10:39:43~
├── toto.txt.14752.2020-12-19@10:39:45~
└── toto.txt.14861.2020-12-19@10:39:48~
Now comes the restore playbook:
---
- name: Restore latest file backup
hosts: localhost
gather_facts: false
vars:
my_file: /tmp/test_restore/toto.txt
tasks:
- name: "Find all backups for {{ my_file }}"
find:
recurse: no
paths:
- "{{ my_file | dirname }}"
patterns:
- '{{ my_file | basename }}\..*~'
use_regex: true
register: find_backup
- name: Select the latest backup found on disk
set_fact:
latest_backup: "{{ (find_backup.files | sort(attribute='mtime') | last).path }}"
- name: Show the latest selected backup
debug:
var: latest_backup
- name: "Restore latest backup of {{ my_file }}"
copy:
src: "{{ latest_backup }}"
remote_src: true
dest: "{{ my_file }}"
Which gives:
PLAY [Restore latest file backup] ******************************************************************************************************************************************************************************************************
TASK [Find all backups for /tmp/test_restore/toto.txt] *********************************************************************************************************************************************************************************
ok: [localhost]
TASK [Select the latest backup found on disk] ******************************************************************************************************************************************************************************************
ok: [localhost]
TASK [Show the latest selected backup] *************************************************************************************************************************************************************************************************
ok: [localhost] => {
"latest_backup": "/tmp/test_restore/toto.txt.14861.2020-12-19@10:39:48~"
}
TASK [Restore latest backup of /tmp/test_restore/toto.txt] *****************************************************************************************************************************************************************************
changed: [localhost]
PLAY RECAP *****************************************************************************************************************************************************************************************************************************
localhost : ok=4 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
If you run that playbook a second time, the last task will report ok instead of changed, demonstrating if needed that the file has the same content as the latest backup.