Groups
Groups

Multiple and/or conditions in when wont work

6,045 views
Skip to first unread message

ajay jiwanand

unread,
Jun 29, 2017, 5:34:16 PM6/29/17
to Ansible Project
I am having issues with using multiple conditions in when to validate whether or not to run a task.

Basically I am using extrended variables within the ansible command to state what sort of updates I want to run like this:
ansible-playbook site.yml -i inventory --ask-vault -u (username)-e "security=true restart=true" -k -K

- name: Update all packages
  yum:
     name: "*"
     state: latest
     exclude: "kernel*"
  when: security is not defined or kernel is not defined  or specified_packages is not defined and ansible_os_family == "RedHat"  

However I can not figure out a combination to get this conditional to run properly. Everytime I run it the playbook continues to run the task when I dont want it to. I already experimented with adding another variable to specify if I want to skip this task only but I would prefer it to automatically get skipped when I specify to run another type of update.

I've tried the following:

 (security is not defined or kernel is not defined  or specified_packages is not defined) and (ansible_os_family == "RedHat")
 (security is not defined or kernel is not defined  or specified_packages is not defined) and ansible_os_family == "RedHat"

or even:

when: ansible_os_family == "RedHat"
when: security is not defined or kernel is not defined  or specified_packages is not defined

Kai Stian Olstad

unread,
Jun 30, 2017, 2:17:29 AM6/30/17
to ansible...@googlegroups.com
On 29. juni 2017 23:00, ajay jiwanand wrote:
> I am having issues with using multiple conditions in when to validate
> whether or not to run a task.
>
> Basically I am using extrended variables within the ansible command to
> state what sort of updates I want to run like this:
> ansible-playbook site.yml -i inventory --ask-vault -u (username)-e
> "security=true restart=true" -k -K
>
> - name: Update all packages
> yum:
> name: "*"
> state: latest
> exclude: "kernel*"
> when: security is not defined or kernel is not defined or
> specified_packages is not defined and ansible_os_family == "RedHat"
>
> However I can not figure out a combination to get this conditional to run
> properly. Everytime I run it the playbook continues to run the task when I
> dont want it to.

When do you want the task to run?


> I already experimented with adding another variable to
> specify if I want to skip this task only but I would prefer it to
> automatically get skipped when I specify to run another type of update.
>
> I've tried the following:
>
> (security is not defined or kernel is not defined or specified_packages
> is not defined) and (ansible_os_family == "RedHat")
> (security is not defined or kernel is not defined or specified_packages
> is not defined) and ansible_os_family == "RedHat"
>
> or even:
>
> when: ansible_os_family == "RedHat"
> when: security is not defined or kernel is not defined or
> specified_packages is not defined
>


--
Kai Stian Olstad

Brian Coca

unread,
Jun 30, 2017, 7:54:16 AM6/30/17
to Ansible Project
Multiple AND/OR do work, are you sure your conditions are being met?
----------
Brian Coca
Message has been deleted

ajay jiwanand

unread,
Jun 30, 2017, 1:05:58 PM6/30/17
to Ansible Project, ansible-pr...@olstad.com
i want to run the task when ansible_os_family == "RedHat" (this works) AND if none of the following variables are set (security,kernel,specified_packages) through extended variables (-e)

ajay jiwanand

unread,
Jun 30, 2017, 1:10:18 PM6/30/17
to Ansible Project
 Im posting my stack overflow question as it is much more clear:


I am having issues when trying to use multiple and/or conditionals in a when statement to decide whether a task needs to be ran or not. Basically I am making a playbook to do automated system patching with options for security patches, kernel only patches and to specify packages in a var file.

I run the playbook with the following commands and define the variables through extended variables option (-e)

ansible-playbook site.yml -i inventory --ask-vault -u (username)-e "security=true restart=true" -k -K

By default the playbook will update every package on the system except kernel but I would like to skip that action if I specify any of a few variables. The code I have is the following:

- name: Update all packages yum: name: "*" state: latest exclude: "kernel*" when: security is not defined or kernel is not defined or specified_packages is not defined and ansible_os_family == "RedHat"

Ive tried all of the following combinations:

when: (ansible_os_family == "RedHat") and (security is defined or kernel is defined or specified_packages is defined)

when: (ansible_os_family == "RedHat") and (security == true or kernel == true or specified_packages == true ) <- this case throws a not defined error because i don't define all variables every time i run the playbook

when: ansible_os_family == "RedHat" when: security is defined or kernel is defined or specified_packages is defined

Note: I am aware and have used an extra variable such as "skip" to skip this task and use the when clause when: ansible_os_family == "RedHat" and skip is not defined but would prefer not have my users need to use an extra variable just to skip this default action.

I also am not using tags as I am gathering a list of packages before and after the upgrade to compare and report in the end so I wont be able to run those as they are local action commands. This is why I'm using one role with multiple tasks turned on and off via extended variables. I am open to any suggestion that rewrites the playbook in a more efficient way as I am sort of a noob.

Kai Stian Olstad

unread,
Jun 30, 2017, 2:48:02 PM6/30/17
to ansible...@googlegroups.com
On 30. juni 2017 19:10, ajay jiwanand wrote:
> Im posting my stack overflow question as it is much more clear:
>
>
> Ask Question <https://stackoverflow.com/questions/ask>
> up vote0down votefavorite
> <https://stackoverflow.com/questions/44838421/ansible-multiple-an-or-conditionals-in-when-clause/44839565?noredirect=1#>
>
> I am having issues when trying to use multiple and/or conditionals in a
> when statement to decide whether a task needs to be ran or not. Basically I
> am making a playbook to do automated system patching with options for
> security patches, kernel only patches and to specify packages in a var file.
>
> I run the playbook with the following commands and define the variables
> through extended variables option (-e)
>
> ansible-playbook site.yml -i inventory --ask-vault -u (username)-e
> "security=true restart=true" -k -K
>
> By default the playbook will update every package on the system except
> kernel but I would like to skip that action if I specify any of a few
> variables. The code I have is the following:
>
> - name: Update all packages yum: name: "*" state: latest exclude: "kernel*"
> when: security is not defined or kernel is not defined or
> specified_packages is not defined and ansible_os_family == "RedHat"

Your last three posted have different explanation of what you are trying
to achieve, but according to this post I think you are looking for this

when: not (security is defined or kernel is defined or
specified_packages is defined) and ansible_os_family == "RedHat"

This only run on RedHat when none of the variables is set.


--
Kai Stian Olstad

Daniel JD

unread,
Jun 30, 2017, 3:38:12 PM6/30/17
to Ansible Project
You could use the intersect filter from jinja2.

I am thinking about sth. like the following:

when: ansible_os_family == "RedHat" and not vars.keys() | intersect([security,kernel,specified_packages])

ajay jiwanand

unread,
Jun 30, 2017, 4:31:04 PM6/30/17
to Ansible Project, ansible-pr...@olstad.com
My bad I was working with many different solutions and  combinations so I got confused. I tried tons of complicated ways .. can't believe such a simple one worked lol. I probably over complicated it but what you suggested works great!

when: not (security is defined or kernel is defined or 
specified_packages is defined) and ansible_os_family == "RedHat" 

Thanks!

ajay jiwanand

unread,
Jun 30, 2017, 4:39:45 PM6/30/17
to Ansible Project
This doesn't work as if I put the second value (in this case kernel) it tries to check it throws an error saying security is undefined. I found that jinja2 templates dont seem to work in the when clause. I tried many jinja2 templates that should work in regular situations but they failed (e.g when: security|d('') = ' ' ..etc or even when: security | default('false') = false). Kai's response works the best although I found a workaround to use false/true flags.

Daniel JD

unread,
Jul 2, 2017, 1:45:36 PM7/2/17
to Ansible Project
The jinja2 template, does work in the when clause.
In fact, you dont even need the curly brakets.

My example gave you an error because i missed the quotes around the items. The items arent variables, these are strings. So you cant get an "is not defined" with that code!

The following code skips the task:

 - hosts: all
  
   vars:
     var1: True
     security: Hello
 
   tasks:
 
     - name: This is a test task
       debug:
         msg: Yo
       when: var1 and not vars.keys() | intersect(["security","kernel","specified_packages"])

This code runs it:

 - hosts: all
  
   vars:
     var1: True
 
   tasks:
 
     - name: This is a test task
       debug:
         msg: Yo
       when: var1 and not vars.keys() | intersect(["security","kernel","specified_packages"])
Reply all
Reply to author
Forward
0 new messages
Search
Clear search
Close search
Google apps
Main menu