Paweł Halicki
Paweł Halicki

Reputation: 90

Ansible template with list of hosts excluding current

I'm super fresh to ansible and creating a playbook that in one of the tasks should copy templated file and replace values in 2 lines. First line should have current hostname, and in second semicolon separated list of all other hosts (used in the play) - it will be different group

First line is super easy, as it's just:

localnode={{ inventory_hostname }}

but I'm having problem with exclusion in the second line. I'd like something similar to:

{% for host in groups.nodes -%} # but without inventory_hostname 
othernodes={{ host }}{% if not loop.last %};{% endif %}
{%- endfor %}

Given the inventory of:

nodes:
  hosts:
    hosta:
    hostb:
    hostc:
    hostd:

I'd like to get following output (example for hostd):

localnode=hostd
othernodes=hosta,hostb,hostc

I'll be very grateful for all hints on possible solution

Upvotes: 2

Views: 2073

Answers (1)

Vladimir Botka
Vladimir Botka

Reputation: 68024

Create the list of hosts without inventory_hostname and use it in the template

    - set_fact:
        list_other_hosts: "{{ groups.nodes|difference([inventory_hostname]) }}"

Simplify the template

    othernodes={{ list_other_hosts|join(';') }}

As an example, the inventory
shell> cat hosts
test_jails:
  hosts:
    test_01:
    test_02:
    test_03:

and the play

- hosts: test_jails
  tasks:
    - set_fact:
        list_other_hosts: "{{ groups.test_jails|
                              difference([inventory_hostname]) }}"
    - debug:
        msg: "{{ msg.split('\n') }}"
      vars:
        msg: |-
          localnode={{ inventory_hostname }}
          othernodes={{ list_other_hosts|join(';') }}

give

    TASK [debug] ********************************************************
    ok: [test_01] => {
        "msg": [
            "localnode=test_01", 
            "othernodes=test_02;test_03"
        ]
    }
    ok: [test_02] => {
        "msg": [
            "localnode=test_02", 
            "othernodes=test_01;test_03"
        ]
    }
    ok: [test_03] => {
        "msg": [
            "localnode=test_03", 
            "othernodes=test_01;test_02"
        ]
    }

Upvotes: 6

Related Questions