Home > Software engineering >  Using Split and join together in Ansible template file
Using Split and join together in Ansible template file

Time:09-02

I want to use hostnames of a group in ansible inventory in a template bash script file. This is my inventory:

[group_srv]
srv1.co.company
srv2.co.company
srv3.co.company

This is that I wrote in script.sh.j2

for i in '{{ groups['group_srv'][0:3].split('.')[0] | join(' ') }}' ; do
  echo $i
done

This is my desired output, but I cannot use split() and join() together.

for i in  'srv1' 'srv2' 'srv3'; do
  echo $i
done

Any help is appreciated.

CodePudding user response:

Ansible provides a magic variable containing the short name for each server in your inventory (i.e. the first string before the first dot): inventory_hostname_short

You can access all servers vars in an other magic var: hostvars

You can use the map filter to:

  1. extract values for a list of keys inside a dict (e.g. the relevant hosts for your group in hostvars)
  2. select a single key in a list of dictionaries (e.g. the short inventory name in each extracted server vars).

Putting it all together:

for i in '{{ groups['group_srv'] | map('extract', hostvars) | map(attribute='inventory_hostname_short') | join("' '") }}' ; do
  echo $i
done

CodePudding user response:

In Jinja2 loop you can use filters.
{% if not loop.last %} {% endif %} adds a white space after every element except the last one.

for i in {% for host in groups['group_srv'] %}'{{ host.split('.')[0] }}'{% if not loop.last %} {% endif %}{% endfor %} ; do
  echo $i
done

Result:

for i in 'test-001' 'test-002' ; do
  echo $i
done

CodePudding user response:

The declaration below does the job

short_0_3: "{{ groups.group_srv[0:3]|
               map('split', '.')|
               map('first')|
               join(' ') }}"

The next option is the extraction of the variable inventory_hostname_short

short_0_3: "{{ groups.group_srv[0:3]|
               map('extract', hostvars, 'inventory_hostname_short')|
               join(' ') }}"

Both options give

short_0_3: srv1 srv2 srv3

Example of a complete playbook for testing

- hosts: all
  gather_facts: false
  vars:
    short_0_3: "{{ groups.group_srv[0:3]|
                   map('split', '.')|
                   map('first')|
                   join(' ') }}"
  tasks:
    - block:
        - shell: "for i in {{ short_0_3 }}; do echo $i; done"
          register: out
        - debug:
            var: out.stdout_lines
      delegate_to: localhost
      run_once: true
shell> cat hosts
[group_srv]
srv1.co.company
srv2.co.company
srv3.co.company
srv4.co.company
srv5.co.company
  • Related