Ansible templates. Joining item vars on one line with static text.

Hello.

Consider I have this variable list that can contain as little as 1 and up to 4 items.

ldapservers:

  • server1
  • server2

Consider this line in my ldap.conf template.

URI ldap://{{ ldapservers(’ ') }}/

I would like the resulting file to look like this:

URI ldap://server1/ ldap://server2/

I know I can use “join” with something like this, but how do I keep the “URI” the " ldap://" and the trailing “/” consistent without adding them to the variable.

URI ldap://{{ ldap_srv_fqdn|join(’ ') }}/

Thanks in advance.

Mike

There may be more elegant ways to achieve this, but I had a similar requirement from some Eventstore config a while back and ended up with a construct like:

Construct each GossipSeed from ansible_play_hosts minus the inventory_host

{%- set seeds = %}
{%- for host in ansible_play_hosts %}
{%- if host != inventory_hostname %}
{{ seeds.append(hostvars[host][‘ansible_host’] ~ ‘:2113’) }}
{%- endif %}
{%- endfor %}

GossipSeed: {{ seeds | join(‘,’) }}

In your case you could maybe do something like (untested):

Construct list of LDAP server URIs

{%- set ldap_sever_list = %}
{%- for server in ldapservers %}
{{ ldap_sever_list.append(‘ldap://’ ~ server ~ ‘/’) }}
{%- endfor %}

URI: {{ ldap_server_list | join(‘,’) }}

ldapservers:
    - server1
    - server2

I would like the resulting file to look like this:

URI ldap://server1/ ldap://server2/

Put the below declarations as appropriate

    ldapservers: [server1, server2]
    uri: "{{ ['ldap://'] |
             product(ldapservers) | map('join') |
             product(['/'])| map('join') |
             join(' ') }}"

Then, the template is trivial

    - copy:
        content: |
          URI {{ uri }}
        dest: /tmp/uri.test

gives what you want

cat /tmp/uri.test

URI ldap://server1/ ldap://server2/

HTH,

There may be more elegant ways to achieve this

The below declaration should to the job

    seeds: "{{ ansible_play_hosts |
               difference([inventory_hostname]) |
               map('extract', hostvars, 'ansible_host') |
               product([':2113']) |
               map('join') |
               join(',') }}"

{%- set seeds = %}
{%- for host in ansible_play_hosts %}
  {%- if host != inventory_hostname %}
    {{ seeds.append(hostvars[host]['ansible_host'] ~ ':2113') }}
  {%- endif %}
{%- endfor %}

GossipSeed: {{ seeds | join(',') }}

For example, given the inventory

  > cat hosts
  host_A ansible_host=10.1.0.51
  host_B ansible_host=10.1.0.52
  host_C ansible_host=10.1.0.53

the below play

  - hosts: all
    vars:
      seeds: "{{ ansible_play_hosts |
                 difference([inventory_hostname]) |
                 map('extract', hostvars, 'ansible_host') |
                 product([':2113']) |
                 map('join') |
                 join(',') }}"
    tasks:
      - debug:
          var: seeds

gives (abridged)

ok: [host_A] =>
  seeds: 10.1.0.53:2113,10.1.0.52:2113
ok: [host_B] =>
  seeds: 10.1.0.53:2113,10.1.0.51:2113
ok: [host_C] =>
  seeds: 10.1.0.51:2113,10.1.0.52:2113

HTH,

Thank you both for the suggestions. Much appreciated.