2

I have the following task in a playbook:

- name: task xyz  
  copy:  
    src="{{ item }}"  
    dest="/tmp/{{ item }}"  
  with_items: "{{ y.z }}"  
  when: y.z is defined  

y.z is not defined, so I'm expecting the task to be skipped. Instead, I receive:

FAILED! => {"failed": true, "msg": "'dict object' has no attribute 'z'"

I have found: How to run a task when variable is undefined in ansible? but it seems I implemented just that. What am I doing wrong here?

Community
  • 1
  • 1
jdoestackoverflow
  • 607
  • 1
  • 7
  • 15
  • I don't know if the lack of an existing attribute `z` in the `y` dict is the same as `y.z` being undefined. Undefined does not necessarily mean the same thing as, say, null, empty, nil, false, etc. – Matthew Schuchard Nov 04 '16 at 14:24
  • as a different way to check, you could try `'z' not in y` (i know that does not answer yout question but it could keep you going. – user2599522 Nov 04 '16 at 14:46
  • Do you mean to try `'z' in y`? In any case, I tried both, but the result was the same. – jdoestackoverflow Nov 04 '16 at 14:57

1 Answers1

9

The problem here is that with_items is evaluated before when. Actually in real scenarios you put item in the when conditional. See: Loops and Conditionals.

This task will work for you:

- name: task xyz
  copy:  
    src: "{{ item }}"  
    dest: "/tmp/{{ item }}"  
  with_items: "{{ (y|default([])).z | default([]) }}"
techraf
  • 64,883
  • 27
  • 193
  • 198
  • Referring to the documentation for completeness: "Combining when with with_items (see Loops), be aware that the when statement is processed separately for each item." (http://docs.ansible.com/ansible/playbooks_conditionals.html) – jdoestackoverflow Nov 04 '16 at 15:01
  • 1
    I'm not sure what you mean by your comment. I included a direct link to the statement you cited in my answer. – techraf Nov 04 '16 at 15:03
  • Ah, somehow missed it. You're correct, your answer was already as complete as can be. – jdoestackoverflow Nov 04 '16 at 15:10