This is a text-only version of the following page on https://raymii.org:
---
Title       : 	Ansible - Only if a file exists or does not exist
Author      : 	Remy van Elst
Date        : 	27-12-2014
URL         : 	https://raymii.org/s/tutorials/Ansible_-_Only_if_a_file_exists_or_does_not_exist.html
Format      : 	Markdown/HTML
---



This Ansible playbook example helps you execute actions only if a file exists or
does not exist. If you for example have a command you need to run to generate a
certificate (or Diffie Hellman parameters for nginx) you only want to do that
once. The command itself is not convergent so it will run with every ansible
run. However, the command creates a file and Ansible is able to check if that
file exists. If the file exists, it will not execute the action. The same goes
for checking if a file does exist and only executing the action if it exists.
(The action you want to do will remove that file).

<p class="ad"> <b>Recently I removed all Google Ads from this site due to their invasive tracking, as well as Google Analytics. Please, if you found this content useful, consider a small donation using any of the options below:</b><br><br> <a href="https://leafnode.nl">I'm developing an open source monitoring app called  Leaf Node Monitoring, for windows, linux & android. Go check it out!</a><br><br> <a href="https://github.com/sponsors/RaymiiOrg/">Consider sponsoring me on Github. It means the world to me if you show your appreciation and you'll help pay the server costs.</a><br><br> <a href="https://www.digitalocean.com/?refcode=7435ae6b8212">You can also sponsor me by getting a Digital Ocean VPS. With this referral link you'll get $100 credit for 60 days. </a><br><br> </p>


The below example command will generate [Diffi Hellman parameters for NGINX
ssl][2]. This command creates the file `/etc/ssl/certs/dhparam.pem`. It should
run only if that file does not exist (because only newly deployed servers will
not have the file), if the file exist there is no need to run again.

    
    
    - name: generate dh params
    command: sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048 
    args: 
      creates: /etc/ssl/certs/dhparam.pem
    

Ansible has the `creates` option in the `command` module. Give it a filename
(directories will not work) and if it already exists Ansible will skip the
action.

The same goes for only executing an action if a file exists. The command you are
using will remove that file, so only if the file is there the action should be
executed. Just as the `creates` option, there is the `removes` option. For the
`removes` option, you need at least Ansible 0.8.

The below example is for a custom piece of software one of my clients uses. If
we deploy a new version, we check out the code repository and run a script to
install a new version. That script will only run when the configuration file is
renamed to `software.conf.upgrade`. After the upgrade it renamed that config
file to the original `software.conf` and also puts the config in its database.
It is sadly proprietary software and the manufacturer has stated they are not
changing the behavior to a more sane default. The below example will only run
the upgrade script when the file `/etc/software/software.conf.upgrade` exists.
Since the script removes it, the next time Ansible runs it does not try to
upgrade the software.

    
    
    - name: upgrade software
    command: /opt/software/bin/upgrade 
    args:
      removes: etc/software/software.conf.upgrade
    

[Documentation for the Command Module][3]

If you have other commands which do not support the `creates` option, you need
to first use the `stat` module and register the result of that. This example is
for the Shorewall firewall. We first check if the rules file exists:

    
    
    - name: check if rules file exists
      stat: 
        path: /etc/shorewall/rules
      register: shorewall_rules
    

We fill the `shorewall_rules` variable with the result of this action. The next
two actions add a rule to the rules file and restart the firewall, but only if
the rules file exists:

    
    
    - name: add firewall rule for ssh
      lineinfile: 
        dest: /etc/shorewall/rules 
        state: present 
        regexp: "^ACCEPT net0:192\.0\.2\.22 \$FW tcp 5666" 
        line: "ACCEPT net0:192.0.2.22 $FW tcp 5666"
      when: shorewall_rules.stat.exists == true
    
    - name: restart shorewall
      command: "shorewall restart"
      when: shorewall_rules.stat.exists == True
    

If you want to do stuff when a file is not present, you can check if the result
is `False`, like so:

    
    
    - action: example
      when: stat_result.stat.exists == False
    

   [1]: https://www.digitalocean.com/?refcode=7435ae6b8212
   [2]: https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html
   [3]: http://docs.ansible.com/command_module.html

---

License:
All the text on this website is free as in freedom unless stated otherwise. 
This means you can use it in any way you want, you can copy it, change it 
the way you like and republish it, as long as you release the (modified) 
content under the same license to give others the same freedoms you've got 
and place my name and a link to this site with the article as source.

This site uses Google Analytics for statistics and Google Adwords for 
advertisements. You are tracked and Google knows everything about you. 
Use an adblocker like ublock-origin if you don't want it.

All the code on this website is licensed under the GNU GPL v3 license 
unless already licensed under a license which does not allows this form 
of licensing or if another license is stated on that page / in that software:

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

Just to be clear, the information on this website is for meant for educational 
purposes and you use it at your own risk. I do not take responsibility if you 
screw something up. Use common sense, do not 'rm -rf /' as root for example. 
If you have any questions then do not hesitate to contact me.

See https://raymii.org/s/static/About.html for details.