Can I combine with_items and when?

61 views
Skip to first unread message

Nico Sabbi

unread,
Feb 26, 2018, 9:39:10 AM2/26/18
to Ansible Project
HI,
can I combine when: and with_items clauses as in this example?

  become: true
  become_user: root
  tasks:
    - block:
      - debug:
          msg: "riga {{item}}"
      - user:
          name: "{{ item.split(':')[0] }}"
          home: "{{ item.split(':')[1] }}"
        when: item search(":")
        with_items: [ "abc:def", "yyy.zzz"]

The sad output is the following, indicating that "item" is undefined  in the loop.

TASK [debug] ***********************************************************************************************************************************************************************************************
fatal: [localhost]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'item' is undefined\n\nThe error appears to have been in '/home/nico2601/block.yml': line 25, column 9, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n    - block:\n      - debug:\n        ^ here\n\nexception type: <class 'ansible.errors.AnsibleUndefinedVariable'>\nexception: 'item' is undefined"}
to retry, use: --limit @/home/nico2601/block.retry


What I want to do is ensuring that the user before the : is set only when the string that I'm looping over does contain : 
What's the right way to do it?
Thanks.

Kai Stian Olstad

unread,
Feb 26, 2018, 10:38:58 AM2/26/18
to ansible...@googlegroups.com
On Monday, 26 February 2018 15.39.09 CET Nico Sabbi wrote:
> HI,
> can I combine when: and with_items clauses as in this example?
>
> become: true
> become_user: root
> tasks:
> - block:
> - debug:
> msg: "riga {{item}}"
> - user:
> name: "{{ item.split(':')[0] }}"
> home: "{{ item.split(':')[1] }}"
> when: item search(":")
> with_items: [ "abc:def", "yyy.zzz"]
>
> The sad output is the following, indicating that "item" is undefined in
> the loop.

when is executing before the loop so that's the reason this will not work.


> TASK [debug]
> ***********************************************************************************************************************************************************************************************
> fatal: [localhost]: FAILED! => {"msg": "The task includes an option with an
> undefined variable. The error was: 'item' is undefined\n\nThe error appears
> to have been in '/home/nico2601/block.yml': line 25, column 9, but may\nbe
> elsewhere in the file depending on the exact syntax problem.\n\nThe
> offending line appears to be:\n\n - block:\n - debug:\n ^
> here\n\nexception type: <class
> 'ansible.errors.AnsibleUndefinedVariable'>\nexception: 'item' is undefined"}
> to retry, use: --limit @/home/nico2601/block.retry
>
>
> What I want to do is ensuring that the user before the : is set only when
> the string that I'm looping over does contain :
> What's the right way to do it?

If you but the user code in a file and use include_tasks it will work.

user.yml
---
- user:
name: "{{ item.split(':')[0] }}"
home: "{{ item.split(':')[1] }}"

Then replace the user in block with include_tasks

- include_tasks: user.yml
with_items: [ "abc:def", "yyy.zzz"]


--
Kai Stian Olstad

flowerysong

unread,
Feb 26, 2018, 11:14:19 AM2/26/18
to Ansible Project


On Monday, February 26, 2018 at 9:39:10 AM UTC-5, Nico Sabbi wrote:
HI,
can I combine when: and with_items clauses as in this example?

  become: true
  become_user: root
  tasks:
    - block:
      - debug:
          msg: "riga {{item}}"
      - user:
          name: "{{ item.split(':')[0] }}"
          home: "{{ item.split(':')[1] }}"
        when: item search(":")
        with_items: [ "abc:def", "yyy.zzz"]

The sad output is the following, indicating that "item" is undefined  in the loop.

TASK [debug] ***********************************************************************************************************************************************************************************************
fatal: [localhost]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'item' is undefined\n\nThe error appears to have been in '/home/nico2601/block.yml': line 25, column 9, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n    - block:\n      - debug:\n        ^ here\n\nexception type: <class 'ansible.errors.AnsibleUndefinedVariable'>\nexception: 'item' is undefined"}
to retry, use: --limit @/home/nico2601/block.retry

You'll note that this error is from the 'debug' task, which has neither a loop nor a 'when' clause. `item` is undefined because `item` has not been defined for that task.

If you were attempting to apply the loop to the entire block, that is not supported.

Kai Stian Olstad

unread,
Feb 26, 2018, 11:19:29 AM2/26/18
to ansible...@googlegroups.com
On Monday, 26 February 2018 17.14.19 CET flowerysong wrote:
> You'll note that this error is from the 'debug' task, which has neither a
> loop nor a 'when' clause. `item` is undefined because `item` has not been
> defined for that task.

You are right, I don't know what I was thinking.

So Nico, forget what I wrote.


--
Kai Stian Olstad

Nico Sabbi

unread,
Feb 26, 2018, 11:22:28 AM2/26/18
to Ansible Project

OK, it's working now.  Thanks!


  become: true
  become_user: root
  tasks:
    - block:
      #- debug:
      #    msg: "riga {{item}}"
      - include_tasks: user.yml
        when: item | search(":")
        with_items: [ "abc:/home/def", "ghi:/home/jkh"]

But as noted by floweryoursong...

Nico Sabbi

unread,
Feb 26, 2018, 11:23:45 AM2/26/18
to Ansible Project


Il giorno lunedì 26 febbraio 2018 16:14:19 UTC, flowerysong ha scritto:



You'll note that this error is from the 'debug' task, which has neither a loop nor a 'when' clause. `item` is undefined because `item` has not been defined for that task.

If you were attempting to apply the loop to the entire block, that is not supported.

Yes, I was trying to loop the whole block, the equivalent  of
while(something)
{
-1
-2
-3
}

So ansible can't do it?

Kai Stian Olstad

unread,
Feb 26, 2018, 11:29:23 AM2/26/18
to ansible...@googlegroups.com
You can't loop block. To loop two or more tasks you would need to put it in a file and use include_tasks as I described.

Allowed directives for block is listed here
https://docs.ansible.com/ansible/latest/playbooks_keywords.html#block


--
Kai Stian Olstad

Brian Coca

unread,
Feb 26, 2018, 12:06:23 PM2/26/18
to Ansible Project
FYI, when executes INSIDE the loop, contrary to what was mentioned above.

--
----------
Brian Coca

Kai Stian Olstad

unread,
Feb 26, 2018, 12:17:12 PM2/26/18
to ansible...@googlegroups.com
On Monday, 26 February 2018 18.06.09 CET Brian Coca wrote:
> FYI, when executes INSIDE the loop, contrary to what was mentioned above.

Yeah, it was a brain fart on my side, don't know why since I use when and loop a lot.

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