If Statement 1 Or Statement 2 In Jinja2 Template

Hi All,

(I hope this is the correct place to post this.)

I’ve got the following statements in a Template (.j2) file, but it is obviously wrong. Could someone please point out where I am wrong and what the correct syntax is (I’ve Googled, but can’t seem to find anything - I swear, Google is getting worse and worse these days).

My aim is to have “Extra Stuff” included only if the host belongs to either Group1 or Group2 (or both).

Stuff
{% if inventory_hostname in groups.group1 or inventory_hostname in groups.group2 %}
Large amount of Extra Stuff
{% endif %}
More Stuff

Thanks in advance

Dulux -Oz

I don’t see anything “obviously wrong” with this. Why do you believe it’s wrong?

Hi @flowerysong,

I believe its wrong because ansible won’t compile/run the playbook which deals with that template, and the playbook was running fine until I expanded the relevant line from {% if inventory_hostname in groups.group1 %} to {% if inventory_hostname in groups.group1 or inventory_hostname in groups.group2 %}. :smile:

But like you, I can’t see anything “obviously wrong” either.

Cheers
Dulux-Oz

If I had this issue I’d try adding some debugging, for example:

The `inventory_hostname` is {{ inventory_hostname }}.

The `groups.group1` variable is of type: {{  groups.group1 | ansible.builtin.type_debug }}
and it has the value:

{{ groups.group1 | ansible.builtin.to_yaml }}

Try adding some brackets?

{% if (inventory_hostname in groups.group1) or (inventory_hostname in groups.group2) %}

Or perhaps an extra if and brackets?

{% (if inventory_hostname in groups.group1) or (if inventory_hostname in groups.group2) %}

Ovbs I’m guessing at this point :wink:

I copy-n-pasted your template, changed group1 and group2 to names of groups we have, and it worked just fine.

Then I added a misspelling to my group2 analog, and it fails.

I believe your inventory doesn’t include a group2, at least not the way you spelled it.

1 Like

So perhaps something like this might work?

{% ((if groups.group1 is defined) and
     (if inventory_hostname in groups.group1)) or
   ((if groups.group2 is defined) and
    (if inventory_hostname in groups.group2))
%}

:woman_shrugging:

This is not a useful description of the problem you’re encountering. If you want people to be able to help you, you need to provide some level of useful information (in this case, the text of the error output by Ansible when you try to run the playbook.)

It’s easier to handle that case by inverting the condition and checking against the list of groups that the current host is in.

{% if 'group1' in group_names or 'group2' in group_names %}
4 Likes

Thanks for everyone for chipping in answers and suggestions.

The solution that I got working was to use the line: {% if (inventory_hostname in groups.group1) or (inventory_hostname in groups.group2) %}, which was originally missing the ( ).

Thanks everyone
Dulux-Oz

1 Like

Glad you got something working, but the parentheses make no difference in that expression. You must have also fixed the underlying issue, which I’m guessing was a typo in a group name.

Either way, the better solution — the best suggestion offered in the thread — is the one from @flowerysong:

More generally, if you have a bunch (more than two) groups to check, or if the list of relevant groups is already in a variable, it may be better to write the expression thus:

{% if ['group1',
       'group2',
       'group3',
       'group4',
       'group5''] | intersect(group_names) | length > 1 %}

or

{% if my_group_list | intersect(group_names) | length > 1 %}
2 Likes

…but the parentheses make no difference in that expression. You must have also fixed the underlying issue, which I’m guessing was a typo in a group name.

:smile: That may be your belief (based on your experience, etc) but FTR, the only change made (anywhere in the Ansible ecosystem) was the addition of two ( characters and two ) characters in the locations specified - nothing, and I mean nothing - else was changed anywhere (& I say that as someone who has been troubleshooting computers, software, and networks for over 40 years, so I know how to isolate issues and test for them systematically - feel free to check out my Resume/Credentials if you have trouble accepting my statement(s)).

As a newcomer to Ansible I’m still getting tripped up on both semantics and also the best way to “skin the cat” - which is why I ask questions instead of wasting time floundering around. Having absorbed all of the above suggestions, I now agree with you and @flowerysong that his/her suggestion is the “best” way to do things and have implement such both in my initial issue and others, so thank you to both of you (and all the others) for all the help - it really is appreciated.

Until next time

Cheers
Dulux-oz

1 Like

The parenthesis are syntactic grouping. Usually they’re employed for doing complex conditions like, for example, (2>3 or 3<4) and (mars is in retrograde or 2==1). The only difference of {% if (inventory_hostname in groups.group1) or (inventory_hostname in groups.group2) %} vs {% if inventory_hostname in groups.group1 or inventory_hostname in groups.group2 %} is readability; they both evaluate to the same thing. It is incorrect to boil this down to “a belief”. It would be like saying adding a comment or a newline to the end of a file made it work.

1 Like

It’s not so much a belief as a programming fact. The parentheses make no difference in that context. I’d love to see the git diff on that file to see what else was changed.

As a ‘newcomer’ to ansible you are also a newcomer to jinja templating, so you don’t have all the answers. Glad you decided to take some users’ advice and got the problem fixed. But “doing this for 40 years” isn’t the flex you think it is. No one in IT cares what you did in 1994, they care what you did in 2024…

1 Like

:slight_smile: It’s unfortunate you never posted the error you were getting. We’ve heard such claims before — sometimes from our own mouths.

I literally copy-n-pasted your expression from your first post

Then defined an inventory with group1 and group2, put my current machine into group1 and ran it. It worked beautifully. Moved my machine from group1 to group2 and that worked as expected. Then I stuck a typo into the group names and it died with red text saying:

fatal: [tango.trailsong.org]: FAILED! => {“msg”: “The task includes an option with an undefined variable.. ‘dict object’ has no attribute ‘grooup1’\n\nThe error appears to be in ‘/home/utoddl/ansible/Dulux-Oz_00.yml’: line 7, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n tasks:\n - name: The test\n ^ here\n”}

Since you never posted the error you got, we’ve no way of knowing what the problem was, but it wasn’t the lack of parentheses.

I also have been making mistakes in this field professionally for 42 years. Here’s a picture of my key-punch cards to prove it! Only now I can make mistakes on a scale we couldn’t imagine back then. But even then the refrain “I didn’t change anything else” was a clear sign that, well, you know… :slight_smile:

Cheers!

2 Likes