I'm trying to get IP address from inventory using Jinja2 loop index inside hostvars (from Ansible):
Inventory is like:
all:
hosts:
host1:
ansible_host: 192.168.1.1
host2:
ansible_host: 192.168.1.2
host3:
ansible_host: 192.168.1.3
service_nodes:
hosts:
host1:
host2:
host3:
template.yml
is like:
...
{% for host in service_nodes %}
- {{ loop.index }}:{{ hostvars[groups.service_nodes[{{ loop.index }}]].ansible_host }}
...
{% endfor %}
...
I ran the playbook but encountered:
{"changed": false, "msg": "AnsibleError: template error while templating string: expected token ':', got '}'.
And I've checked on AnsibleError: template error while templating string: expected token 'end of statement block', got '{' but seems it's not my answer.
Also, I tried these on the template but failed:
{% set idx = loop.index %}
- {{ loop.index }}:{{ hostvars[groups.service_nodes[{{ idx }}]].ansible_host }}
and
- {{ loop.index }}:{{ hostvars[groups.service_nodes["{{ loop.index }}"]].ansible_host }}
Use the directive children
to declare the group of hosts service_nodes
shell> cat hosts
all:
hosts:
host1:
ansible_host: 192.168.1.1
host2:
ansible_host: 192.168.1.2
host3:
ansible_host: 192.168.1.3
children:
service_nodes:
hosts:
host1:
host2:
host3:
Test it. See the output of the command
shell> ansible-inventory -i hosts --list --yaml
all:
children:
service_nodes:
hosts:
host1:
ansible_host: 192.168.1.1
host2:
ansible_host: 192.168.1.2
host3:
ansible_host: 192.168.1.3
ungrouped: {}
Then the playbook below
shell> cat playbook.yml
- hosts: all
tasks:
- template:
src: hosts.yml.j2
dest: /tmp/hosts.yml
delegate_to: localhost
run_once: true
and the template
shell> cat hosts.yml.j2
{% for host in groups.service_nodes %}
- {{ loop.index }}:{{ hostvars[host]['ansible_host'] }}
{% endfor %}
give
shell> cat /tmp/hosts.yml
- 1:192.168.1.1
- 2:192.168.1.2
- 3:192.168.1.3