I am attempting to pass a list of lists via a registered variable to a template in which I then attempt to loop over the outer list. However, the template is looping over the entire list as a string, and each iteration of the loop outputs one character instead of a sublist as I intend. Does anyone have any thoughts on how I might tweak what I’m doing to accomplish this? At this point, I’m looking at attempting to bundle the first two parts of the below task list into a single task that creates what I want with Jinja2 directly instead of asking Ansible to do so.
Thank you,
Nathan
/home/nathan/ANSIBLE/TEMPLATE/roles/3850/tasks/main.yml:
Your issue is that the variable is a python string and iterating over it gives back each character.
This is probably not the best way to fix this, but should work:
Creating a custom jinja2 filter that does eval(str_argument) will do. I managed to get one working as follows:
cat ./filter_plugins/utils.py
“”"
Simple jinja2 filters for ansible playbooks:
See http://grokbase.com/t/gg/ansible-project/14btv17s4n/how-to-add-custom-jinja-filters
“”"
class FilterModule(object):
def filters(self):
return {
‘eval’: lambda s: eval(s),
some day add more filters here …
}
The ./filter_plugins/ folder is relative to the location where I execute the playbook from.
Now use that filter in your jinja2 template, where you reference the string var which is actually a list:
{% for iranges in range_list.results[0].stdout |eval %}
HTH,
Yassen
Forgot to note that you must trust the output that you "eval()"uate. Another (safer) option would be to output valid Json and then parse it on the ansible/python side.
Yassen
Thank you, Yassen,
That helped tremendously by doing exactly what I was looking for and saving me quite a bit of time doing it another way. Regarding your suggestion, if I output my list as json, would I set it as a fact in the playbook filtered with “|from_json” or would that best be implemented in the for loop in my template?
Regards,
Nathan
In case you are not going to use that python structure elsewhere – I guess it is a matter of taste; I would simply filter some_result.stdout in the template using from_json:
{% for item in some_result.stdout |from_json %}
…
{% endfor %}
(I omit lots of details, you see.)
If your script has issues and cannot dump that json stuff (but spits some error instead) then the template rendering will fail, which seems fine – you should still be able to see the error and diagnose it.
Y.