How to check if a file exists in Ansible?

I have to check whether a file exists in /etc/. If the file exists then I have to skip the task. Here is the code I am using:

- name: checking the file exists command: touch file.txt when: $(! -s /etc/file.txt) 

12 Answers

You can first check that the destination file exists or not and then make a decision based on the output of its result:

 tasks: - name: Check that the somefile.conf exists stat: path: /etc/file.txt register: stat_result - name: Create the file, if it doesnt exist already file: path: /etc/file.txt state: touch when: not stat_result.stat.exists 
9

The stat module will do this as well as obtain a lot of other information for files. From the example documentation:

- stat: path=/path/to/something register: p - debug: msg="Path exists and is a directory" when: p.stat.isdir is defined and p.stat.isdir 
1

This can be achieved with the stat module to skip the task when file exists.

- hosts: servers tasks: - name: Ansible check file exists. stat: path: /etc/issue register: p - debug: msg: "File exists..." when: p.stat.exists - debug: msg: "File not found" when: p.stat.exists == False 

In general you would do this with the stat module. But the command module has the creates option which makes this very simple:

- name: touch file command: touch /etc/file.txt args: creates: /etc/file.txt 

I guess your touch command is just an example? Best practice would be to not check anything at all and let ansible do its job - with the correct module. So if you want to ensure the file exists you would use the file module:

- name: make sure file exists file: path: /etc/file.txt state: touch 
3

Discovered that calling stat is slow and collects a lot of info that is not required for file existence check.
After spending some time searching for solution, i discovered following solution, which works much faster:

- raw: test -e /path/to/something && echo -n true || echo -n false register: file_exists - debug: msg="Path exists" when: file_exists.stdout == "true" 
2

I find it can be annoying and error prone to do a lot of these .stat.exists type checks. For example they require extra care to get check mode (--check) working.

Many answers here suggest

  • get and register
  • apply when register expression is true

However, sometimes this is a code smell so always look for better ways to use Ansible, specifically there are many advantages to using the correct module. e.g.

- name: install ntpdate package: name: ntpdate 

or

- file: path: /etc/file.txt owner: root group: root mode: 0644 

But when it is not possible use one module, also investigate if you can register and check the result of a previous task. e.g.

# jmeter_version: 4.0 - name: Download Jmeter archive get_url: url: " jmeter_version }}.tgz" dest: "/opt/jmeter/apache-jmeter-{{ jmeter_version }}.tgz" checksum: sha512:eee7d68bd1f7e7b269fabaf8f09821697165518b112a979a25c5f128c4de8ca6ad12d3b20cd9380a2b53ca52762b4c4979e564a8c2ff37196692fbd217f1e343 register: download_result - name: Extract apache-jmeter unarchive: src: "/opt/jmeter/apache-jmeter-{{ jmeter_version }}.tgz" dest: "/opt/jmeter/" remote_src: yes creates: "/opt/jmeter/apache-jmeter-{{ jmeter_version }}" when: download_result.state == 'file' 

Note the when: but also the creates: so --check doesn't error out

I mention this because often these less-than-ideal practices come in pairs i.e. no apt/yum package so we have to 1) download and 2) unzip

Hope this helps

You can use Ansible stat module to register the file, and when module to apply the condition.

- name: Register file stat: path: "/tmp/test_file" register: file_path - name: Create file if it doesn't exists file: path: "/tmp/test_file" state: touch when: file_path.stat.exists == False 

Below is the ansible play i used to remove the file when the file exists in the OS end.

 - name: find out /etc/init.d/splunk file exists or not' stat: path: /etc/init.d/splunk register: splunkresult tags: - always - name: 'Remove splunk from init.d file if splunk already running' file: path: /etc/init.d/splunk state: absent when: splunkresult.stat.exists == true ignore_errors: yes tags: - always 

I have used play condition as like below

when: splunkresult.stat.exists == true --> Remove the file 

you can give true/false based on your requirement

when: splunkresult.stat.exists == false when: splunkresult.stat.exists == true 
vars: mypath: "/etc/file.txt" tasks: - name: checking the file exists command: touch file.txt when: mypath is not exists 
3

A note on relative paths to complement the other answers.

When doing infrastructure as code I'm usually using roles and tasks that accept relative paths, specially for files defined in those roles.

Special variables like playbook_dir and role_path are very useful to create the absolute paths needed to test for existence.

1

I use this code and it works fine for folders and files. Just make sure there is no trailing spaces after the folder name. If folder exists , the file_exists.stdout will be "true" otherwise it will just be an empty string ""

- name: check filesystem existence shell: if [[ -d "/folder_name" ]]; then echo "true"; fi register: file_exists - name: debug data debug: msg: "Folder exists" when: file_exists.stdout == "true" 

You can use shell commands to check if file exists

 - set_fact: file: "/tmp/test_file" - name: check file exists shell: "ls {{ file }}" register: file_path ignore_errors: true - name: create file if don't exist shell: "touch {{ file }}" when: file_path.rc != 0 

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

You Might Also Like