Re: Understanding the "by design" behavior of "when" conditionals with "with_items"

56 views
Skip to first unread message

Brian Coca

unread,
Feb 2, 2017, 8:44:16 AM2/2/17
to RaSca, Ansible Project
This will avoid any and all problems with my_key definition.

with_file: "{{ (my_key is defined)|ternary(my_key|default('') +
'.pub', [])}}"


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

RaSca

unread,
Feb 6, 2017, 9:41:41 AM2/6/17
to Ansible Project, rasc...@gmail.com
Hi Brian,
thanks for your answer. I changed the yaml as you suggested:

- name: Configure key on remote host
  authorized_key
:
    user
: root
    key
: "{{ item }}"

  with_file
: "{{ (my_key is defined)|ternary(my_key|default('') + '.pub', [])}}"

  become
: true
 
when: do_the_test|bool

But it stills fail to locate the file:

TASK [bug_20919_bis : Configure key on remote host] ****************************
task path
: /home/rasca/Red-Hat/ansible/tests/roles/bug_20919_bis/tasks/main.yml:12
 
[WARNING]: Unable to find 'rasca.pub' in expected paths.


File lookup using None as file
fatal
: [192.168.122.100]: FAILED! => {
   
"failed": true,
   
"msg": "could not locate file in lookup: rasca.pub"
}
 to
retry, use: --limit @/home/rasca/Red-Hat/ansible/tests/bug_20919_bis.retry

So the problem here does not seem to be related at what is inside the variable passed to "with_file", but to the fact that independently from what's passed and from the "when:" variable, ansible looks for the file.

Thanks,

Raoul

RaSca

unread,
Feb 6, 2017, 9:41:41 AM2/6/17
to Ansible Project, bc...@ansible.com
Hi everybody,
following this bug [1] I've opened yesterday and the suggestion from Brian I want to understand in depth what is considered by design inside Ansible about "when".

Now, leaving aside the usage of "when" inside roles, let's start with this simple example:

---
- name: Create key
  delegate_to
: localhost
  command
: >
    ssh
-keygen -f {{ my_key }} -N ''
   
-C 'ansible_generated_virt_host'
   
-t rsa -b 4096
  args
:
    creates
: "{{ my_key }}"
 
when: do_the_test|bool



- name: Configure key on remote host
  authorized_key
:
    user
: root
    key
: "{{ item }}"
  with_file
:

   
- "{{ my_key }}.pub"

  become
: true
 
when: do_the_test|bool

Two tasks, each one depending on the "do_the_test" condition.
Now, if you execute this you will get an error concerning the fact that "{{ my_key }}.pub" is not existing. And of course it is not, because it should be created by the first task, which is skipped because of the "when:" condition.
Now, you will say that as stated here [2] this is by design, in fact it explicitly says:

be aware that the when statement is processed separately for each item.

So in this case, if I want to skip that task I need to find another method, since Ansible will try to "resolve" the variable "{{ item }}" loading *in any case* the file(s) declared in "with_file".

And here comes my question: I understood technically why my problem is happening (and if you see the bug I already found a workaround), but how can I reach what I want then? Is there something that makes you skip the whole task without processing each item? The point is that if I want a task to be skipped I don't want to care about what's inside it, I just don't want to execute (or parse, or load) anything around it.

Thanks for your attention,

Raoul

Brian Coca

unread,
Feb 6, 2017, 10:44:13 AM2/6/17
to Ansible Project
The with_ section gets executed BEFORE the when, so you cannot use
when to avoid the with_ from being evaluated, the when runs once per
item (inside the with_ loop) to allow the task to be conditional PER
ITEM.

This is as documented :
http://docs.ansible.com/ansible/playbooks_conditionals.html#loops-and-conditionals


----------
Brian Coca
Reply all
Reply to author
Forward
0 new messages