Thomas
Thomas

Reputation: 31

Printing ip addresses in a loop

I'm trying to put together a line with the ip addresses of my cluster in a loop:

set_fact: nodelist={%for host in groups['proxmox-cluster']%}"{{hostvars[host].ansible_all_ipv4_addresses|string}}"{% if not loop.last %},{% endif %}{% endfor %}

But when I try to put this line into a file with

 lineinfile:
        path: "/etc/security/access.conf"
        line: "+:root:{{ nodelist }}"

I get:

"[u'192.168.31.238']","[u'192.168.31.248']","[u'192.168.31.252']","[u'192.168.31.250', u'192.168.1.250', u'192.168.32.250', u'192.168.33.250']"

instead of

192.168.31.238,192.168.31.248,192.168.31.252,192.168.31.250,192.168.1.250,192.168.32.250,192.168.33.250

Upvotes: 2

Views: 690

Answers (3)

Nick
Nick

Reputation: 2034

The reason for this is that hostvars[host].ansible_all_ipv4_addresses is an array. That is why you're printing a joined list of strings inside arrays "[u'192.168.31.238']","[u'192.168.31.248']"...

If you only want to print the default ipv4 addresses you can replace your hostvars expression with:

hostvars[host].ansible_default_ipv4.address

If you want to print the first address in the total list of addresses you can replace your hostvars expression with:

hostvars[host].ansible_all_ipv4_addresses | first

If you want to include all ip addresses from all hosts you will need two loops. This can either be done with Jinja2 template syntax, clever filter chains or both. For example replacing the entire expression with a combination of a jinja2 loop with a filter will give you:

{% for host in groups['proxmox-cluster'] %}"{{ hostvars[host].ansible_all_ipv4_addresses | join(',') }}"{% if not loop.last %},{% endif %}{% endfor %}

Personally I try to avoid mixing Jinja2 template syntax inside ansible tasks/playbooks. There is usually a cleaner way using just filter chains. In your case for example you might do something like this:

- name: Print ips in access.conf
  lineinfile:
    path:  /etc/security/access.conf
    line: "{{ groups['proxmox-cluster'] 
            | map('extract', hostvars, 'ansible_default_ipv4')
            | map(attribute='address')
            | join(',') }}"

Upvotes: 1

TinaC
TinaC

Reputation: 276

Try with a filter on nodelist variable in lineinfile module:

lineinfile:
  path: "/etc/security/access.conf"
  line: "{{ nodelist | join(',') }}"

Upvotes: 0

Vladimir Botka
Vladimir Botka

Reputation: 68034

Try simpler version below

- set_fact:
    nodelist: "{{ nodelist|default([]) + hostvars[item].ansible_all_ipv4_addresses }}"
  loop: "{{ groups['proxmox-cluster'] }}"

Upvotes: 0

Related Questions