# When clause with AND and OR condition does not work

**URL:** <https://forum.ansible.com/t/when-clause-with-and-and-or-condition-does-not-work/5112>\
**Category:** Get Help\
**Tags:** playbook, howto\
**Created:** [April 24, 2024, 4:36am UTC](https://forum.ansible.com/t/when-clause-with-and-and-or-condition-does-not-work/5112 "2024-04-24T04:36:52Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Joe](https://avatars.discourse-cdn.com/v4/letter/j/b9e5f3/32.png) [@Joe](https://forum.ansible.com/u/Joe)\
**Post date:** [April 24, 2024, 4:36am UTC](https://forum.ansible.com/t/when-clause-with-and-and-or-condition-does-not-work/5112/1 "2024-04-24T04:36:52Z")

</div>

Hello,

I am attempting to to use a when clause to run a task only when a string is found in 1 registered variable, and either of 2 strings are found inside of another registered variable. The contents of 2 files is registered into these respective variables.

so basically when string1 is found in var1 AND either string2 OR string3 is found in var2  
when:

- ’ “string1” in var1’
- (’ “string2” in var2 or “string3” in var2’ )

Futile example  
I want to run a debug message if the string websrv is found in /etc/hosts and either the string nfssrv1 or the string 192.168.1.1 is found in the /etc/applications file.

Contents of /etc/applications

```auto
oraclehomedir=nfsserv1:/applications/orahome

```

Contents of /etc/hosts

```auto
127.0.0.1 localhost
10.10.10.20 websrv1

```

Playbook:

```auto

- name: Register Hosts
  shell: cat /etc/hosts
  register: var_etchosts

- name: Register File Contents
  shell: cat /etc/applications
  register: var_applications

- name: Show msg when websrv string found in var_etchosts AND either ip OR name found in var_applications 
  debug: 
    msg: "This webserver is pointed to the wrong nfs server"
  when: 
    - ' "websrv" in var_etchosts'
    - ( ' "nfsserv1" in var_applications or "192.168.2.100" in var_applications' )

```

The above does not work and I am not sure why. I am saying if this string is found in 1 var and either of 2 strings is found in another, var print a message. I can use all And logic and it works… For example

```auto

when: 
    - ' "webserv" in var_etchosts'
    - ' "nfsserv2" not in var_applications' 
    - ' "192.168.2.100" not in var_applications'

```

Hope this makes sense

---

<div class="post-metadata">

**Author:** ![kurokobo](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/kurokobo/32/182_2.png) [@kurokobo](https://forum.ansible.com/u/kurokobo)\
**Post date:** [April 24, 2024, 5:07am UTC](https://forum.ansible.com/t/when-clause-with-and-and-or-condition-does-not-work/5112/2 "2024-04-24T05:07:58Z")

</div>

Hi, the most foolproof way to troubleshoot when a condition contains variables and it does not work as expected is, to dump the variables.

```yaml
- name: Register Hosts
  shell: cat /etc/hosts
  register: var_etchosts

- name: Dump variable
  ansible.builtin.debug:
    var: var_etchosts

```

Perhaps you can get following output:

```bash
TASK [Dump variable] *******************************************************************
ok: [...] => {
    "var_etchosts": {
        "changed": true,
        "cmd": "cat /etc/hosts",
        "rc": 0,
        ...
        "stderr": "",
        "stderr_lines": [],
        "stdout": "127.0.0.1 localhost\n10.10.10.20 websrv1",
        "stdout_lines": [
            "127.0.0.1 localhost",
            "10.10.10.20 websrv1"
        ]
    }
}

```

Then you can find that any strings from the file is under `stdout` or `stdout_lines`.

So you should use `<variable_name>.stdout` instead.

```yaml
when: 
  - '"websrv" in var_etchosts.stdout'
  - '"nfsserv1" in var_applications.stdout or "192.168.2.100" in var_applications.stdout'

```

---

<div class="post-metadata">

**Author:** ![flowerysong](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/flowerysong/32/2305_2.png) [@flowerysong](https://forum.ansible.com/u/flowerysong)\
**Post date:** [April 24, 2024, 5:18am UTC](https://forum.ansible.com/t/when-clause-with-and-and-or-condition-does-not-work/5112/3 "2024-04-24T05:18:57Z")

</div>

None of your conditions are correct; did you look at the contents of the registered variables? Also, you have at least two syntax errors in your task list, which makes me wonder whether this is actually something you tried to run.

```yaml
  debug: "This webserver is pointed to the wrong nfs server"

```

This will error out; `debug` takes a `msg` parameter, not a free-form string.

```yaml
    - '"websrv" in var_etchosts

```

This will error out; YAML strings that start with a quote need to be terminated by a matching quote. The condition is also incorrect, because `var_etchosts` is a registered variable so it will have the structure of a task result and this condition will never be true (the result from `shell` is a dictionary that does not have `websrv` as a key.)

```yaml
    - ( '"nfsserv1" in var_applications or "192.168.2.100" in var_applications' )

```

This has the same problem as the previous condition (not checking the correct place in the variable), but also a new mistake that makes it always true. When a YAML string starts with a quote that quote is YAML syntax, not part of the string value, but this string starts with`(` and all of its quotes are part of the string value. Non-empty strings are truthy, so this is the equivalent of `when: ( true )`.

```yaml
- name: Show msg when websrv string found in var_etchosts AND either ip OR name found in var_applications 
  debug:
    msg: This webserver is pointed to the wrong nfs server
  when: 
    - '"websrv" in var_etchosts.stdout'
    - '"nfsserv1" in var_applications.stdout or "192.168.2.100" in var_applications.stdout'

```

---

<div class="post-metadata">

**Author:** ![Joe](https://avatars.discourse-cdn.com/v4/letter/j/b9e5f3/32.png) [@Joe](https://forum.ansible.com/u/Joe)\
**Post date:** [April 24, 2024, 5:48am UTC](https://forum.ansible.com/t/when-clause-with-and-and-or-condition-does-not-work/5112/4 "2024-04-24T05:48:22Z")

</div>

Thank you, Mr Kurokobo.

Yes, I have also tried exactly as you suggested, using stdout. I still don’t get the expected result which I find odd since the stdout indeed includes the expected strings.

I will use the multiple AND conditions without OR. That aside, my AND with OR syntax is indeed supported as far as you can confirm?

Thanks

---

<div class="post-metadata">

**Author:** ![kurokobo](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/kurokobo/32/182_2.png) [@kurokobo](https://forum.ansible.com/u/kurokobo)\
**Post date:** [April 24, 2024, 6:57am UTC](https://forum.ansible.com/t/when-clause-with-and-and-or-condition-does-not-work/5112/5 "2024-04-24T06:57:46Z")

</div>

> [@Joe](#):
>
> That aside, my AND with OR syntax is indeed supported as far as you can confirm?

Yes, it’s supported. The complete snippet of the task from @flowerysong works as expected.

To test conditionals, for example, the `debug` task like following is quite clear and helpful to understand how conditionals works.

```yaml
- debug:
    var: conditionals
  vars:
    conditionals:
      01_websrv: '{{ "websrv" in var_etchosts.stdout }}'
      02_nfsserv1: '{{ "nfsserv1" in var_applications.stdout }}'
      03_192_168_2_100: '{{ "192.168.2.100" in var_applications.stdout }}'
      04_or: '{{ "nfsserv1" in var_applications.stdout or "192.168.2.100" in var_applications.stdout }}'

```

```bash
TASK [debug] ************************************************************
ok: [localhost] => {
    "conditionals": {
        "01_websrv": true,
        "02_nfsserv1": true,
        "03_192_168_2_100": false,
        "04_or": true
    }
}

```

---

<div class="post-metadata">

**Author:** ![Joe](https://avatars.discourse-cdn.com/v4/letter/j/b9e5f3/32.png) [@Joe](https://forum.ansible.com/u/Joe)\
**Post date:** [April 24, 2024, 7:02am UTC](https://forum.ansible.com/t/when-clause-with-and-and-or-condition-does-not-work/5112/6 "2024-04-24T07:02:42Z")

</div>

Mr Kurokobo, thank you, I appreciate this information, this is very useful, I will use this to debug going forward.

---

<div class="post-metadata">

**Author:** ![Joe](https://avatars.discourse-cdn.com/v4/letter/j/b9e5f3/32.png) [@Joe](https://forum.ansible.com/u/Joe)\
**Post date:** [April 24, 2024, 7:28am UTC](https://forum.ansible.com/t/when-clause-with-and-and-or-condition-does-not-work/5112/7 "2024-04-24T07:28:02Z")

</div>

Hello, Flowerysong, I did not see your reply.

Apologies for the sloppy code when creating the post. I see the errors I made there, I should have proofread. I did run the code, just sloppy when posting, I will be careful in the future.

I use the builtin.debug often, I use msg: or var: , just sloppy on my part when posting.

I appreciate your feedback here, very useful. I had not considered the fact that websrv is not a key. I did try stdout and stdout\_lines but I will have to read what you have written here and try to understand and apply it in test. I have much to learn.

Thank you once again

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/ansible/original/1X/1882d9a01da5d8996a862359b0913cc568a39b84.svg) [@system](https://forum.ansible.com/u/system)\
**Post date:** [May 24, 2024, 7:28am UTC](https://forum.ansible.com/t/when-clause-with-and-and-or-condition-does-not-work/5112/8 "2024-05-24T07:28:46Z")

</div>

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.
