Hello,
I have a data structure gathered from a postgres db (external inventory) with a list of json data structures as follows :
[
{‘name’: conf1, ‘myvar1’: 1, ‘myvar2’: blabla},
{‘name’: conf2, ‘myvar1’: 44, ‘myvar2’: hello}
]
And i would like to use a kind of loop to create a file like :
[conf1]
param1 = 1
param2 = blabla
[conf2]
param1 = 44
param2 = hello
I’ve read in the ansible
"
ansible allows Jinja2 loops and conditionals in templates, but in playbooks, we do not use them. Ansible templates are pure machine-parseable YAML. This is an rather important feature as it means it is possible to code-generate pieces of files, or to have other ecosystem tools read Ansible files. Not everyone will need this but it can unlock possibilities.
"
Is there a way to perform that kind of loops please ?
Regards,
Smana
my current script generates this output :
{
“databases”: {
“hosts”: ,
“vars”: {}
},
“webservers”: {
“hosts”: [
“10.18.2.1”,
“10.18.2.2”,
],
“vars”: {}
},
“Site”: {
“children”: [
“databases”,
“webservers”
],
“vars”: [
{
“id”: 4912,
“path”: “test1.mp3”,
}
{
“id”: 4913,
“path”: “test2.mp3”,
}
]
}
}
But i got this error when executing ansible :
/etc/ansible/services/mysite 0 # ansible all -i ./inventory.py
Traceback (most recent call last):
File “/usr/bin/ansible”, line 157, in
(runner, results) = cli.run(options, args)
File “/usr/bin/ansible”, line 79, in run
inventory_manager = inventory.Inventory(options.inventory)
File “/usr/lib/python2.7/dist-packages/ansible/inventory/init.py”, line 101, in init
self.parser = InventoryScript(filename=host_list)
File “/usr/lib/python2.7/dist-packages/ansible/inventory/script.py”, line 47, in init
self.groups = self._parse(stderr)
File “/usr/lib/python2.7/dist-packages/ansible/inventory/script.py”, line 92, in _parse
for k, v in data[‘vars’].iteritems():
AttributeError: ‘list’ object has no attribute ‘iteritems’
I need to iterate on a list of several variables.
Do you think that’s possible ?
Regards,
Smana
Smain,
Although full jinja2 templating is not available in tasks/playbooks, other features like pipes/filters are.Try piping your datastructure with to_json like
- name: do a thing
copy: src=“{{item}}” dest=/foo
with_items: {{output | to_json}}
I used something like this as well, where _requested_hosts was a dict passed in to a task like
[main.yml]
- include: { playbook.yml, _requested_hosts: {{some_dict_defined_in_vars_main.yml}} }
[playbook.yml]
- debug: msg=“{{_requested_hosts | to_json | capture(requested_hosts)}}”
The problem is that passing structures between playbook files seems to serialize it, and this deserializes it.
kesten
I don’t endorse the above suggestion by Kesten, and I’m pretty sure it’s not going to work
You have a list data structure so iteritems isn’t a method on a list.
If you just want to generate the config file I would do this as a template module:
(WARNING: untested general idea)
{% for entry in foo %}
{% for (k,v) in entry.iteritems() %}
{% if k == ‘name’ %}
[{{ v }}]
{% endif %}
{% endfor %}
{% for (k,v) in entry.iteritems() %}
{% if k != ‘name’ %}
{{ k }}={{ v }}
{% endif %}
{% endfor %}
{% endfor %}
- template: src=foo.j2 dest=wherever.out
Note that I’m answering your first question and not your second – your variable structures are different in each.
Hello all,
For information i managed to do what i wanted.
i just changed my list into a dictionnary :
mylist = [ {‘name’: conf1, ‘myvar1’: 1, ‘myvar2’: blabla}, {‘name’: conf2, ‘myvar1’: 44, ‘myvar2’: hello} ]
mydict = { mylist }
then i used this dictionnary in my playbook as follows :
- name: foo configuration
template: src=foo.cfg dest=/etc/foo/{{ item[‘name’] }}.sh
with_items: $mydict
the “item” variable can also be use inside the template.
Thanks for your help.
Regards
No need for the legacy variable here, BTW, just do this:
with_items: mydict