Reputation: 1354
I'm working in a project, and we use ansible to create a deploy a cluster of servers. One of the tasks that I've to implement, is to copy a local file to the remote host, only if that file exists locally. Now I'm trying to solve this problem using this
- hosts: 127.0.0.1
connection: local
tasks:
- name: copy local filetocopy.zip to remote if exists
- shell: if [[ -f "../filetocopy.zip" ]]; then /bin/true; else /bin/false; fi;
register: result
- copy: src=../filetocopy.zip dest=/tmp/filetocopy.zip
when: result|success
Bu this is failing with the following message: ERROR: 'action' or 'local_action' attribute missing in task "copy local filetocopy.zip to remote if exists"
I've tried to create this if with command task. I've already tried to create this task with a local_action, but I couldn't make it work. All samples that I've found, doesn't consider a shell into local_action, there are only samples of command, and neither of them have anything else then a command. Is there a way to do this task using ansible?
Upvotes: 33
Views: 73971
Reputation: 1
Small correction to one of the examples by @awltux, the syntax should be:
- name: "Use lookup to test for local_file or use a default_file"
vars:
local_file: "{{ playbook_dir }}/generated.file"
default_file: "{{ playbook_dir }}/default.file"
file_to_copy: "{{ local_file if lookup( 'file', local_file, errors='ignore') else default_file }}"
copy:
src: "{{ file_to_copy}}"
dest: "{{ remote_file }}"
Upvotes: 0
Reputation: 601
Apologies for resurrecting the dead, this was the first result of my search.
Use the 'file' lookup to try and load the file contents of local files - doesn't work for remote files.
- name: "Use lookup to test for local_file"
vars:
local_file: "{{ playbook_dir }}/generated.file"
remote_file: "~/remote.file"
when: lookup( 'file', local_file, errors='ignore' )
copy:
src: "{{ local_file}}"
dest: "{{ remote_file }}"
Or use it for defaults:
- name: "Use lookup to test for local_file or use a default_file"
vars:
local_file: "{{ playbook_dir }}/generated.file"
default_file: "{{ playbook_dir }}/default.file"
file_to_copy: "{{ local_file if lookup( 'file', local_file, errors='ignore' else default_file )
copy:
src: "{{ file_to_copy}}"
dest: "{{ remote_file }}"
NOTE: Small caveat for Ansible 2.9 is the warning message, even though it's supposed to be 'ignored' - I'd expect this if using the 'warning' option.
Upvotes: 1
Reputation: 546
If you don't wont to set up two tasks, you could use 'is file' to check if local files exists:
tasks:
- copy: src=/a/b/filetocopy.zip dest=/tmp/filetocopy.zip
when: '/a/b/filetocopy.zip' is file
The path is relative to the playbook directory, so using the magic variable role_path is recommended if you are referring to files inside the role directory.
Ref: http://docs.ansible.com/ansible/latest/playbooks_tests.html#testing-paths
Upvotes: 26
Reputation: 9088
A more comprehensive answer:
If you want to check the existence of a local file before performing some task, here is the comprehensive snippet:
- name: get file stat to be able to perform a check in the following task
local_action: stat path=/path/to/file
register: file
- name: copy file if it exists
copy: src=/path/to/file dest=/destination/path
when: file.stat.exists
If you want to check the existence of a remote file before performing some task, this is the way to go:
- name: get file stat to be able to perform check in the following task
stat: path=/path/to/file
register: file
- name: copy file if it exists
copy: src=/path/to/file dest=/destination/path
when: file.stat.exists
Upvotes: 37
Reputation: 597
Fileglob permits a lookup of an eventually present file.
- name: copy file if it exists
copy: src="{{ item }}" dest=/destination/path
with_fileglob: "/path/to/file"
Upvotes: 4
Reputation: 3808
How about this?
tasks:
- copy: src=../filetocopy.zip dest=/tmp/filetocopy.zip
failed_when: false
This will copy the file to the target if it exists locally. If it does not exists, it simply does nothing since the error is ignored.
Upvotes: 1
Reputation: 714
Change your first step into the following on
- name: copy local filetocopy.zip to remote if exists
local_action: stat path="../filetocopy.zip"
register: result
Upvotes: 24