Bug Report
ansible 1.7
Running OS from : OSX 10.9
Managing: Ubuntu 14.04
When a task is used with "with_dict" and "when" and the value of when evaluates to false, ansible tries to check for a dict value and fails when it should skip the task.
hosts:
[test]
testhost
playbook.yml:
- hosts: all
tasks:
- name: Delete a user
user: name="{{item}}" state=absent
when: users_deleted is defined
with_dict: users_deleted
command: ansible-playbook -i hosts playbook.yml
I have not defined users_deleted so this task should be skipped.
In playbook.yml if you change "with_dict" to "with_items" the task is skipped correctly.
Results from running the task using "with_items" instead of "with_dict":
PLAY [all] ********************************************************************
GATHERING FACTS ***************************************************************
ok: [testhost]
TASK: [Delete a user] *********************************************************
skipping: [testhost] => (item=users_deleted)
PLAY RECAP ********************************************************************
testhost : ok=2 changed=0 unreachable=0 failed=0
PLAY [all] ********************************************************************
GATHERING FACTS ***************************************************************
ok: [testhost]
TASK: [Delete a user] *********************************************************
fatal: [testhost] => with_dict expects a dict
FATAL: all hosts have already failed -- aborting
PLAY RECAP ********************************************************************
testhost : ok=1 changed=0 unreachable=1 failed=0
Hi!
This is a bit of a misunderstanding, but the conditional here is evaluated for each and every item, which is a needed feature. In order to evaluate it for each item, it must start with something for which it can iterate.
As such, you might wish to do something like:
with_dict: "{{ users_deleted | default({}) }}"
Which should help resolve this.
It would also allow you to remove the when clause because the list would be of zero length instead of undefined.
Feel free to stop by ansible-project if you have further questions and we'd be glad to help with this one.
Thanks!
I ended up using:
with_dict: users_deleted | default({})
This works as expected and skips the task. As a user this was a little confusing as I would expect to be able to use "when:" consistently when I need a conditional for a task. Thanks for clarifying this!
I still got this error in version 2.0.1.0
[DEPRECATION WARNING]: Skipping task due to undefined Error, in the future this will be a fatal error.. This feature will be removed in a future
release. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.
fatal: [xxx.xxx.xxx.xxx]: FAILED! => {"failed": true, "msg": "with_dict expects a dict"}
I have to use ignore_errors
to bypass it.
Most helpful comment
Hi!
This is a bit of a misunderstanding, but the conditional here is evaluated for each and every item, which is a needed feature. In order to evaluate it for each item, it must start with something for which it can iterate.
As such, you might wish to do something like:
with_dict: "{{ users_deleted | default({}) }}"
Which should help resolve this.
It would also allow you to remove the when clause because the list would be of zero length instead of undefined.
Feel free to stop by ansible-project if you have further questions and we'd be glad to help with this one.
Thanks!