Closed c-mart closed 7 years ago
@ansible ping, this issue is waiting for your response. click here for bot help
I can reproduce this. Here's the simplest playbook I can come up with:
---
- hosts: tag_environment_stage:&tag_roles_backstage
gather_facts: False
remote_user: ubuntu
sudo: True
tasks:
- name: restart all the nodewebkits
monit: name={{ item.name }} state=restarted
with_items: node_webkits
Here's the error:
fatal: [ec2-54-163-173-183.compute-1.amazonaws.com]: FAILED! => {"failed": true, "msg": "the field 'args' has an invalid value, which appears to include a variable that is undefined. The error was: 'unicode object' has no attribute 'name'\n\nThe error appears to have been in '/mnt/nfshome/plotly/streambed/deployment/playbook_stage.yml': line 7, column 5, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n tasks:\n - name: restart all the nodewebkits\n ^ here\n"}
As above, this worked in 2.1.x but is broken in 2.2.x.
The interesting part is if I remove the optional "name" from my task I get:
fatal: [ec2-54-163-173-183.compute-1.amazonaws.com]: FAILED! => {"failed": true, "msg": "the field 'args' has an invalid value, which appears to include a variable that is undefined. The error was: 'unicode object' has no attribute 'name'\n\nThe error appears to have been in '/mnt/nfshome/plotly/streambed/deployment/playbook_stage.yml': line 7, column 5, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n tasks:\n - monit: name={{ item.name }} state=restarted\n ^ here\nWe could be wrong, but this one looks like it might be an issue with\nmissing quotes. Always quote template expression brackets when they\nstart a value. For instance:\n\n with_items:\n - {{ foo }}\n\nShould be written as:\n\n with_items:\n - \"{{ foo }}\"\n"}
Unfortunately, quoting {{ item.name }}
does not fix the issue.
To be clear, here is the playbook used to produce the second error:
---
- hosts: tag_environment_stage:&tag_roles_backstage
gather_facts: False
remote_user: ubuntu
sudo: True
tasks:
- monit: name={{ item.name }} state=restarted
with_items: node_webkits
Hi!
Thanks very much for your submission to Ansible. It sincerely means a lot to us.
We believe the ticket you have filed is being somewhat misunderstood, as one thing works a little differently than stated.
You should have been getting deprecation warnings with those plays in 2.0/2.1 as 'bare' variables in with_
were scheduled for removal, you need to change your plays to:
with_items: "{{groups['target-hosts']}}"
or
with_items: "{{node_webkits}}"
This was done so we can distinguish between 'undefined' and 'simple strings' in loop items.
In the future, this might be a topic more well suited for the user list, which you can also post here if you'd like some more help with the above.
Thank you once again for this and your interest in Ansible!
Thank you for your time and the helpful reminder! I fixed my code by encapsulating variables in curly braces and quotes.
ISSUE TYPE
COMPONENT NAME
with_items, host groups
ANSIBLE VERSION
CONFIGURATION
https://github.com/cyverse/openstack-ansible-host-prep/blob/master/ansible/ansible.cfg
OS / ENVIRONMENT
Ubuntu 16.04 LTS
SUMMARY
My organization uses a role that generates a list of root passwords, writes them to a file, encrypts them, and sets them on target hosts. It works with Ansible 2.1.2.0 but not with Ansible 2.2.0.0 which was just released to the Ubuntu PPA two days ago.
I think the problem starts with this task:
It's supposed to generate a password corresponding to each host in a group and store it in a
root_pass
variable, so we can later encrypt the passwords and set them on each of the target hosts. The intention is thatroot_pass.results
is a list; each member item in the list is a dictionary that contains astdout
of the generated password, and anitem
showing the name of the host it is generated for.However! In the above task, it looks like
with_items: groups['target_hosts']
isn't actually expanded out to a hostname for each item. If I debug outroot_pass.results
......then I see output like this (repeated for each of the members of target-hosts):
root_pass.results.(item).item
is assigned a string/unicode value ofgroups['target-hosts']
for each member ofroot_pass.results
, rather than the actual name of a host in the target-hosts group.That is weird because I can do the following, and I get the expected results, with
groups['target-hosts']
expanded out to a host for each item:Anyhow, the failure to expand groups['target-hosts'] in the above local_action task seems to break subsequent tasks, which need a way to determine hostnames and passwords:
If I go back in time and install the Ansible 2.1.2.0-1 .DEB from the PPA, then the role completes without error! So, the behavior is definitely new with 2.2.
If we are doing this a stupid way and should refactor, feel free to say so!
STEPS TO REPRODUCE
Run this playbook with real hosts configured in the target-hosts group (like this).
EXPECTED RESULTS
The host-credentials role/playbook completes without error
ACTUAL RESULTS