Can I combine with_items and when?

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.

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

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.

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

So Nico, forget what I wrote.

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…

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

So ansible can’t do it?

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

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.