How to loop through the items in the list which is returned by hostnames from the inventory groups

Viewed 54

Loop through the items. And items are from Inventory groups.

I tried almost all the solutions posted in stackoverflow, but no luck. Here is my playbook:

 ---
 - hosts: dev   
   gather_facts: yes
   become: true   
   become_method: su   
   become_user: xxxxx
 
   tasks:
   - name: Update the file contents
     replace:
       path: "/path/to/file{{ item.path  }}.xml"
       regexp: '(xxxxxxx[\s\S]*yyyyyyy$)'
       replace: "/zzz/zzzz/{{ item.replace }}.dat /qqqq/qqqqq/q"
       backup: yes
     with_items:
       - { path: "{{ groups['dev'] }}", replace: "{{ groups['pc'] }}" }

And this is my inventory:

[dev] 
host1 
host2
 
[pc] 
1234 
6789

I want to execute the task : "Update the file contents" for every hostname under dev group for item.path and item.pc

The result of my execution is:

failed: [host1] (item={u'path': [u'host1', u'host2'], u'replace': [u'1234', u'6789']}) => {"ansible_loop_var": "item", "changed": false, "
item": {"path": ["host1", "host2"], "replace": ["1234", "6789"]}, "msg": "Path /path/to/file[u'host1', u'host2'].xml does not exist !", "rc": 257}

failed: [host2] (item={u'path': [u'host1', u'host2'], u'replace': [u'1234', u'6789']}) => {"ansible_loop_var": "item", "changed": false, "
item": {"path": ["host1", "host2"], "replace": ["1234", "6789"]}, "msg": "Path /path/to/file[u'host1', u'host2'].xml does not exist !", rc": 257}

Expected output:

[host1] (item={u'path': [u'host1'], u'replace': [u'1234']}) "msg": "Path /path/to/file/host1.xml 
[host2] (item={u'path': [u'host2'], u'replace': [u'6789']}) "msg": "Path /path/to/file/host2.xml 

This works fine if I have only 1 hostname in the dev group. I need the task to work for all the hosts when the number of hosts are more than 1.

Can anyone help me solve this?

Thank you!

1 Answers

According to your desired output, there is no need to loop over all hosts.
There is even no need to run the task on the pc hosts group.

- name: Update the file contents
  replace:
    path: "/path/to/file/{{ inventory_hostname_short }}.xml"
    regexp: '(xxxxxxx[\s\S]*yyyyyyy$)'
    replace: "/zzz/zzzz/{{ groups['pc'][groups['dev'].index(inventory_hostname)].split('.')[0] }}.dat /qqqq/qqqqq/q"
    backup: yes
  when: inventory_hostname in groups['dev']

I avoided having the domain name in the hostnames.

{{ groups['pc'][groups['dev'].index(inventory_hostname)].split('.')[0] }}

Here I'm getting the host from group [pc], which its index number is equivalent to the host from group [dev] which the task is currently running on.

  • when running on host1 which has index number 0 in group [dev] ==> groups['pc'][0]
  • when running on host2 which has index number 1 in group [dev] ==> groups['pc'][1]

With .split('.')[0] I'm getting the hostname without domain name.

Related