And, or and not

Today I spent a couple of hours on a condition that contained a mistake. Let me try to help myself and describe a few situations.

Condition?

A condition in Ansible can be described in a when statement. This is a simple example:

- name: do something only to virtual instances
  debug:
    msg: "Here is a message from a guest"
  when: ansible_virtualization_role == "guest"

And

It’s possible to describe multiple conditions. In Ansible, the when statement can be a string (see above) or a list:

- name: do something only to Red Hat virtual instances
  debug:
    msg: "Here is a message from a Red Hat guest"
  when:
    - ansible_virtualization_role == "guest"
    - ansible_os_family == "RedHat"

The above example will run when it’s both a virtual instance and it’s a Red Hat-like system.

Or

Instead of combining (‘and’) conditions, you can also allow multiple condition where either is true:

- name: do something to either Red Hat or virtual instances
  debug:
    msg: "Here is a message from a Red Hat system or a guest"
  when:
    - ansible_virtualization_role == "guest" or ansible_os_family == "RedHat"

I like to keep lines short to increase readability:

  when:
    - ansible_virtualization_role == "guest" or
      ansible_os_family == "RedHat"

And & or

You can also combine and and or:

- name: do something to a Debian or Red Hat, if it's a virtual instances
  debug:
    msg: "Here is a message from a Red Hat or Debian guest"
  when:
    - ansible_virtualization_role == "guest"
    - ansible_os_family == "RedHat" or ansible_os_family == "Debian"

In

It’s also possible to check if some pattern is in a list:

- name: make some list
  set_fact:
    allergies:
      - apples
      - bananas

- name: Test for allergies
  debug:
    msg: "A match was found: "
  when: item in allergies
  loop:
    - pears
    - milk
    - nuts
    - apples

You can have multiple lists and check multiple times:

- name: make some list
  set_fact:
    fruit:
      - apples
      - bananas
    dairy:
      - milk
      - eggs

- name: Test for allergies
  debug:
    msg: "A match was found: "
  when:
    - item in fruit or
      item in dairy
  loop:
    - pears
    - milk
    - nuts
    - apples

Negate

It’s also possible to have search in a list negatively. This is where it gets difficult: (for me!)

- name: make some list
  set_fact:
    fruit:
      - apples
      - bananas
    dairy:
      - milk
      - eggs

- name: Test for allergies
  debug:
    msg: "No match was found: "
  when:
    - item not in fruit
    - item not in dairy
  loop:
    - pears
    - milk
    - nuts
    - apples

The twist here is that both conditions (and) should not be true.

Well, I’ll certainly run into some issue again in the future, hope this helps you (and me) if you ever need a complex condition in Ansible.