problem with with_items + when in ansible 2.2

162 views
Skip to first unread message

Spike

unread,
Dec 23, 2016, 2:27:55 PM12/23/16
to ansible...@googlegroups.com
Hi,

I found this bug, which is closed, but I believe I'm still seeing the same problem:

Ansible 2.x errors on the task with the `with_items` loop with `when: some_var is defined` condition when it is used in a role, but not in a play

In my case I have a very simple task in a role:

    - name: install sw requested for this box
      apt:
        name: "{{item}}"
        state: present
        install_recommends: yes
      with_items: "{{additional_sw}}"
      when: additional_sw is defined

this fails with an error:

fatal: [localhost]: FAILED! => {"failed": true, "msg": "'additional_sw' is undefined"}

which is true, but the point of the when: is exactly to avoid that. To make it even weirder, I tried to move the when: to a block wrapping that task, and still get the same error.

Eventually I defined a default value to an empty list in role/defaults/main.yml:

additional_sw: []

this worked but I'd still prefer to resolve the above problem.

any idea what's going on?

thanks,

Spike

Kai Stian Olstad

unread,
Dec 23, 2016, 3:17:07 PM12/23/16
to ansible...@googlegroups.com
On 23. des. 2016 20:27, Spike wrote:
> I found this bug, which is closed, but I believe I'm still seeing the same
> problem:
>
> Ansible 2.x errors on the task with the `with_items` loop with `when:
> some_var is defined` condition when it is used in a role, but not in a play
> https://github.com/ansible/ansible/issues/14383
>
> In my case I have a very simple task in a role:
>
> - name: install sw requested for this box
> apt:
> name: "{{item}}"
> state: present
> install_recommends: yes
> with_items: "{{additional_sw}}"
> when: additional_sw is defined
>
> this fails with an error:
>
> fatal: [localhost]: FAILED! => {"failed": true, "msg": "'additional_sw' is
> undefined"}
>
> which is true, but the point of the *when:* is exactly to avoid that. To
> make it even weirder, I tried to move the *when:* to a *block* wrapping
> that task, and still get the same error.

You have the point of when wrong, this is by design.
When is applied to every iteration of elements in with_items.

You can read more about it here
https://docs.ansible.com/ansible/playbooks_conditionals.html#loops-and-conditionals


> Eventually I defined a default value to an empty list in
> role/defaults/main.yml:
>
> additional_sw: []
>
> this worked but I'd still prefer to resolve the above problem.
>
> any idea what's going on?

Just remove the when, an change the with_items to
with_items: "{{ additional_sw | default([]) }}"

This translate to, if additional_sw variable is not defined use a empty
list, the result is that the task will be skipped.


--
Kai Stian Olstad

Spike

unread,
Dec 23, 2016, 4:13:41 PM12/23/16
to ansible...@googlegroups.com
thanks for the explanation Kai, makes sense, it effectively does the same thing I've done by setting a default value, but indeed I didn't understand how when worked in conjunction with the with_items.

Here's however something else related that's happening and I'm not understanding: why does this happens also if I move the task in a block and apply the when to that?

  - block:
    - name: install sw requested for this box
      apt:
        name: "{{item}}"
        state: present
        install_recommends: yes
      with_items: "{{additional_sw}}"
    when: additional_sw is defined

shouldn't the task only be considered if the block is executed? why in this case i'm still getting the same error? and in fact, I also see the problem elsewhere with an include, which is even stranger:

#tasks/main.yml
  - include: interfaces.yml
    when: server_interfaces is defined
    tags:
      - netwrk

#tasks/interfaces.yml

  - name: generate new interfaces file
    template:
      src: interfaces.j2
      dest: /etc/network/interfaces
      owner: root
      group: adm
      mode: 0640
    notify:
      - restart network

  - name: setup rt_tables
    lineinfile:
      dest: /etc/iproute2/rt_tables
      regexp: "^{{item.id}} "
      line: "{{item.id}}      {{item.tname}}"
    with_items: "{{server_rt_tables}}"
    when: server_rt_tables is defined

If I don't define server_interfaces I would expect the interfaces.yml to be skipped. Is that not correct? Instead what I'm seeing is the "generate new interfaces" task being skipped while the setup rt_tables throws the same error. It seems like the tasks are "interpreted" even tho they are supposed to be skipped, which doesn't make sense to me.

any thoughts?

thanks,

Spike


--
You received this message because you are subscribed to the Google Groups "Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-proje...@googlegroups.com.
To post to this group, send email to ansible...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ansible-project/003862c1-f05f-8c81-3d79-87a08a587b39%40olstad.com.
For more options, visit https://groups.google.com/d/optout.

Kai Stian Olstad

unread,
Dec 23, 2016, 5:07:47 PM12/23/16
to ansible...@googlegroups.com
On 23. des. 2016 22:13, Spike wrote:
> thanks for the explanation Kai, makes sense, it effectively does the same
> thing I've done by setting a default value, but indeed I didn't understand
> how when worked in conjunction with the with_items.
>
> Here's however something else related that's happening and I'm not
> understanding: why does this happens also if I move the task in a block and
> apply the when to that?

You should really read the documentation, it's documented.
https://docs.ansible.com/ansible/playbooks_blocks.html


> * - block:*
> * - name: install sw requested for this box*
> * apt:*
> * name: "{{item}}"*
> * state: present*
> * install_recommends: yes*
> * with_items: "{{additional_sw}}"*
> * when: additional_sw is defined*
>
> shouldn't the task only be considered if the block is executed? why in this
> case i'm still getting the same error? and in fact, I also see the problem
> elsewhere with an include, which is even stranger:

All the tasks in a block inherit the when, so it's the same as adding a
when on all the task.


> *#tasks/main.yml*
> * - include: interfaces.yml*
> * when: server_interfaces is defined*
> * tags:*
> * - netwrk*
>
> *#tasks/interfaces.yml*
>
> * - name: generate new interfaces file*
> * template:*
> * src: interfaces.j2*
> * dest: /etc/network/interfaces*
> * owner: root*
> * group: adm*
> * mode: 0640*
> * notify:*
> * - restart network*
>
> * - name: setup rt_tables*
> * lineinfile:*
> * dest: /etc/iproute2/rt_tables*
> * regexp: "^{{item.id <http://item.id>}} "*
> * line: "{{item.id <http://item.id>}} {{item.tname}}"*
> * with_items: "{{server_rt_tables}}"*
> * when: server_rt_tables is defined*
>
> If I don't define server_interfaces I would expect the interfaces.yml to be
> skipped. Is that not correct? Instead what I'm seeing is the "generate new
> interfaces" task being skipped while the setup rt_tables throws the same
> error. It seems like the tasks are "interpreted" even tho they are supposed
> to be skipped, which doesn't make sense to me.

You should read the entire page that I linked to in my previous mail
https://docs.ansible.com/ansible/playbooks_conditionals.html

All the task in the include inherits the when.
So all task is executed with the when applied, it's same as manually
adding when to every single task.


> any thoughts?

When alway get applied to the tasks, not the include or the block.
And the Ansible documentation is pretty good, I do recommend reading it,
you will pick up many useful things :-)

--
Kai Stian Olstad

Spike

unread,
Dec 23, 2016, 8:54:31 PM12/23/16
to ansible...@googlegroups.com
Kai,

wow, school'ed :). I read the docs way back when I picked up when and blocks for the first time and used them for months without a problem thinking I understood what was going on. So when these issues arose I didn't think of checking again. Obviously I had misunderstood it the first time around. Thank you again for the clarifications and reminders.

Spike 

--
You received this message because you are subscribed to the Google Groups "Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-proje...@googlegroups.com.
To post to this group, send email to ansible...@googlegroups.com.

Kai Stian Olstad

unread,
Dec 24, 2016, 4:37:26 AM12/24/16
to ansible...@googlegroups.com
On 24. des. 2016 02:54, Spike wrote:
> wow, school'ed :).

Sorry about that :-)


> I read the docs way back when I picked up *when* and
> *blocks* for the first time and used them for months without a problem
> thinking I understood what was going on. So when these issues arose I
> didn't think of checking again. Obviously I had misunderstood it the first
> time around. Thank you again for the clarifications and reminders.

I forgot that in 2.0 and 2.1 this gave a deprecation warning with a
message that this feature will be removed in future releases and that it
will be a fatal error.
So you're right, it did work until 2.2.

--
Kai Stian Olstad
Reply all
Reply to author
Forward
0 new messages