Search code examples
ansibleansible-2.xansible-inventoryansible-template

Ansible Jinja2 template for loop


I have two linux servers:

- server1: ip: 10.241.55.6, hostname: server1
- server2: ip: 10.242.55.7, hostname: server2

I have created an ansible inventory file named servers with the content bellow:

[IC]
10.241.55.6
10.241.55.7

Now I have created this jinja2 inventory template file: test.j2 with this content:

[IC]
{% for hostip in groups['IC'] %}
{% if hostip == ansible_default_ipv4.address %}
{{ ansible_default_ipv4.address }} default_hostname={{ ansible_nodename }}
{{ ansible_default_ipv4.address }} default_hostname={{ ansible_nodename }}
{% endif %}
{% endfor %}

And I'm running this ansible playbook:

---
- name: Generate portal inventory file
  hosts: all
  tasks:

   - name: Generate inventory
     delegate_to: localhost
     template:
       src: inventory/test.j2
       dest: inventory/test

The command is: ansible-playbook -i inventory/servers generate-inventory.yml

The final goal is that ansible connects to each of the servers from the inventory files and then based on the jinja2 inventory template, it creates a new inventory file with this format:

[IC]
10.241.55.6 default_hostname=hostname_of_the_server_with_that_ip

and so on...

The issue here with the for loop is that all the entries are with the same server ip (while I should have an entry for each of the servers with their respective hostnames):

[IC]
10.241.55.6 default_hostname=server1
10.241.55.6 default_hostname=server2

What I'm missing here? Also if there is any other better way to achieve this please let me know.


Solution

  • You're using the same variable twice in the template...

    {{ ansible_default_ipv4.address }} default_hostname={{ ansible_nodename }}
    {{ ansible_default_ipv4.address }} default_hostname={{ ansible_nodename }}
    

    ...so of course you're getting two identical lines. It sounds like you want to access the per-host value of this variable, which means you need to access it via hostvars.

    Maybe something like this:

    [IC]
    {% for host in groups['IC'] %}
    {{ hostvars[host].ansible_default_ipv4.address }} default_hostname={{ hostvars[host].ansible_nodename }}
    {% endfor %}