Convert with_X to loop: but when: condition being ignored?

I do not know if this is a bug or I do not know how to use when: with the loop:

The tasks

  • name: debug backuppc_client_mysql_dump
    ansible.builtin.debug:
    msg: “{{ backuppc_client_mysql_dump }}”
    when: backuppc_client_mysql_dump is defined
    tags: backuppc

  • name: set up backuppc user MySQL dump authorized_keys
    ansible.posix.authorized_key:
    user: “{{ backuppc_client_item.0.username }}”
    state: “present”
    key_options: “{{ backuppc_client_item.0.key_options }}”
    key: “{{ backuppc_client_item.1 }}”
    manage_dir: true
    loop: “{{{backuppc_client_mysql_dump|subelements(‘authorized_keys’) }}”
    loop_control:
    loop_var: backuppc_client_item
    when: backuppc_client_mysql_dump is defined
    tags: backuppc

Ansible run
TASK [backuppc-client : debug backuppc_client_mysql_dump] **********************
skipping: [docker.*.com]

TASK [backuppc-client : set up backuppc user MySQL dump authorized_keys] *******
fatal: [docker.*.com]: FAILED! => {“msg”: “obj must be a list of dicts or a nested dict”}

The debug task is skipped because backuppc_client_mysql_dump is not defined. I expect the MySQL dump authorized_keys task to be skipped too but it’s not.

Any help?

when statements with a loop are evaluated for every iteration, and not before the loop happens.

This is documented at: https://docs.ansible.com/ansible-core/devel/user_guide/playbooks_conditionals.html#using-conditionals-in-loops

So one solution would be to put both tasks in a block, and put the when: backuppc_client_mysql_dump is defined condition on the block itself.

blocks are not a way to skip tasks, a 'when' on a block is just for
tasks inside the block to inherit.

Ouch! Then you’d have to put the tasks into their own tasks file, and use include_tasks

Or give backuppc_client_mysql_dump a reasonable |default(...) so that the looped task(s) would do no harm.

blocks are not a way to skip tasks, a 'when' on a block is just fortasks inside the block to inherit.
So one solution would be to put both tasks in a block, and put the `when: backuppc_client_mysql_dump is defined` condition on the block itself.