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
Signup for Exclusive "Subscriber-only" Content