Ansible When Variable is defined or undefined Examples

The Purpose

The purpose of this post is to give you a real-time example and explanation of how ansible variable is defined and not defined (undefined) conditionals are working along with "when" conditional statement and how it controls the flow of the task and the play. The following ansible playbook is created strategically to explain the validation cases of ansible playbook variable is defined or not defined (undefined) along with "when" conditional module

Note*: VLOG of this post is now available at our Youtube channel.  you can find the video at end of this post or go to our channel 

Playbook to Test When Variable is defined

We have created a simple playbook to demonstrate this by example, This ansible-playbook is designed to find the files in a specific directory based on the inputs being passed ( startup arguments) .

In our case, The Startup arguments are the --extra-vars (extra variables) being passed while the ansible playbook is being invoked.  Just for convenience and better understanding, we are going to use the short form of --extra-vars which is -e

Note*: --extra-vars (or) -e is a easiest command line based method and one of the way to pass values (or) set variables in the playbook. just like declaring vars/main.yml file  or defining under – vars inside playbook.

As mentioned above,  the ansible playbook is having a simple find command, to find files in a certain directory, read from the user at startup.  But here is the trick.

When the user defines ( pass it as command line argument with -e) Just the Search String  it brings up all the files in the directory matching the search string.

ansible-playbook FindOldfiles.yml \
-i ansible_hosts \
-e "Directory=/var/tmp/filerepo" \
-e "SearchString=*.txt" 

 

When the user defines Search String as well as the Modified time it brings the matching files which are meeting the age criteria as well.

ansible-playbook FindOldfiles.yml \
-i ansible_hosts \
-e "Directory=/var/tmp/filerepo"\
-e "SearchString=*.txt"  \
-e "mtime=30"

In the second snippet, you can find there is an extra command-line argument (or) extra variable -e "mtime=30" which is a modified time flag. ( typical mtime in find command). It supposed to get 30 days old files for us

Note*:  you can also use +30 and -1 like you typically do in the Unix find command. with this playbook.

 

The Playbook

Consider the following playbook.  The Single Playbook would react and perform two different operations based on the availability of variables. the tasks would be executed when certain variables are defined or not defined.

This is achieved through defined and undefined.  The correct task would be executed based on the variables defined or provided.

---
 - name: Find files - Playbook
   hosts: appservers
   tasks:

   # Case1:  when Search String and Modified time is mentioned
   - name:  Find command with *SEARCH STRING* and *MODIFIED TIME*
     shell: "find {{Directory}} -name '{{SearchString}}' -mtime '{{mtime}}'"
     register: case1output
     when: Directory is defined and SearchString is definedand mtime is defined
     ignore_errors: true

   # Case2: when Only Search String is mentioend but NOT Modified time(age)
   - name:  Find command with only with *SEARCH STRING*
     shell: "find {{Directory}} -name '{{SearchString}}' "
     register: case2output
     when: Directory is defined and SearchString is defined and mtime is not defined
     ignore_errors: true
     
   # In case of Case1 Success
   - name: Case1 Output – Output will be displayed only if Case is Success (or) it will be skipped 
     debug: var=case1output.stdout_lines
     when: case1output.stdout_lines is defined

   # In case of Case2 Success
   - name: Case2 Output – Output will be displayed only if Case is Success (or) it will be skipped 
     debug: var=case2output.stdout_lines
     when: case2output.stdout_lines is defined

 

How,  Ansible Defined and Not Defined works

Here, if you look at the Case1, the condition is to make sure that all the variables are defined and having values.

when: Directory is defined and SearchString is defined and mtime is defined

where we define,  Execute the case1 task when the Directory, Search String and Modified time all three variables are defined.

we are validating if three variables are defined before executing this task. If anyone of these variables is not defined this task would not be executed.

 

On the other hand, Case2 Is more similar, with a tiny difference.

Here we are using not defined and checking only if two values are defined and one is undefined or not defined, then this task would be executed.

this is how we are achieving the controlled execution of a task based on the variable's availability and declaration.

when: Directory is defined and SearchString is defined and mtime is not defined

In the preceding snippets, I have highlighted the text which is different from one another.

 

Realtime Testing of this playbook

I have two linux machines grouped into the host group named appservers  and am going to create a new directory with a few empty files.

Note*:  I preferred to do all these steps with ansible ad-hoc commands. hope you would find it helpful too

Let me introduce you the boxes.

$ ansible appservers – list-hosts -i ansible_hosts 
  hosts (2):
    mwiapp04
    mwiapp05

Yes those are my box names mwiapp04 and mwiapp05

Step1: Create a Directory and Files

$ ansible appservers -m shell -a "mkdir -p /var/tmp/filerepo \
&& cd /var/tmp/filerepo && touch file.txt file1.txt file2.txt file3.txt file4.txt" \
-i ansible_hosts

mwiapp05 | SUCCESS | rc=0 >>
mwiapp04 | SUCCESS | rc=0 >>

 

Step2: Make sure the files are created

$ ansible appservers -m shell -a "ls -lrt /var/tmp/filerepo" -i ansible_hosts 
mwiapp04 | SUCCESS | rc=0 >>
total 0
-rw-rw-r--. 1 vagrant vagrant 0 Nov 30 23:56 file.txt
-rw-rw-r--. 1 vagrant vagrant 0 Nov 30 23:56 file4.txt
-rw-rw-r--. 1 vagrant vagrant 0 Nov 30 23:56 file3.txt
-rw-rw-r--. 1 vagrant vagrant 0 Nov 30 23:56 file2.txt
-rw-rw-r--. 1 vagrant vagrant 0 Nov 30 23:56 file1.txt

mwiapp05 | SUCCESS | rc=0 >>
total 0
-rw-rw-r--. 1 vagrant vagrant 0 Nov 30 23:56 file.txt
-rw-rw-r--. 1 vagrant vagrant 0 Nov 30 23:56 file4.txt
-rw-rw-r--. 1 vagrant vagrant 0 Nov 30 23:56 file3.txt
-rw-rw-r--. 1 vagrant vagrant 0 Nov 30 23:56 file2.txt
-rw-rw-r--. 1 vagrant vagrant 0 Nov 30 23:56 file1.txt

Step3: Now Execute our Playbook

Without modified time

ansible-playbook FindOldfiles.yml \
-i ansible_hosts \
-e "Directory=/var/tmp/filerepo" \
-e "SearchString=*.txt"

With modified time

ansible-playbook FindOldfiles.yml \
-i ansible_hosts \
-e "Directory=/var/tmp/filerepo" \
-e "SearchString=*.txt" \
-e "mtime=10"

The Execution Output - Terminal Recording

 

 

The VLOG of this post

Conclusion

Hope the examples on how to use ansible when defined and undefined

Please leave your rating here [ratings]

Let me know your valuable comments and feel free to write it up in case of any feedback or questions

Thanks,
SaravAK

Follow me on Linkedin My Profile
Follow DevopsJunction onFacebook orTwitter
For more practical videos and tutorials. Subscribe to our channel

Buy Me a Coffee at ko-fi.com

Signup for Exclusive "Subscriber-only" Content

Loading