Issues generating dynamic host in Ansible loop.

I have an ansible play that fetches multiline data from the database and registers it a variable “command_result”

command_result variable has has data like below.

`
host6,host5\targ3
host4,host3\targ1

host1,host2,host5\targ2

`

I need to loop through each line of command_result. Pick the host list for example host6,host5 and execute shell script using shell module by passing respective argument string i.e arg3.

Likewise, the second shell script should run on host4 & host3 and pass arg1 to the shell script.

The final shell script hould run on host1, host2 & host5 and pass arg2 to the shell script.

`

  • name: Add hosts
    add_host:
    name: “{{ item.split(‘\t’)[0] }}”
    file_dets: “{{ item.split(‘\t’)[1] }}”

ansible_host: localhost

ansible_connection: local
groups: dest_nodes
with_items: “{{ command_result.stdout_lines }}”

  • hosts: dest_nodes
    gather_facts: false
    tasks:
  • debug:
    msg: Run the shell script with the arguments {{ file_dets }} here"
    `

This works fine when there is a single host in item.split(‘\t’)[0]

However, I do not know the approach when there are multiple hosts like host6,host5 for {{ item.split(‘\t’)[0] }}

Instead of using add_host, use include_tasks to include a second task file. In there, iterate over a “split by comma” list and adds hosts.

This gives you the second level of iteration.

Dick

@Dick; I need more help please.

This is what I did but it is still failing.

- name: Add hosts
include_tasks: "{{ playbook_dir }}/gethosts.yml"
dest_ip: "{{ item.split('\t')[0] }}"
groups: dest_nodes
file_dets: "{{ item.split('\t')[1] }}"
ansible_host: localhost
ansible_connection: local
with_items: "{{ command_result.stdout_lines }}"

And below is my get_hosts.yml file

add_host:
name: {{ item }}
with_items: "{{ dest_ip.split(',') }}"

Given the input is a list 'db_lines' normalise the data first. For example
the loop below

  vars:
    separator: '\t'
    db_lines:
      - 'host6,host5\targ3'
      - 'host4,host3\targ1'
      - 'host1,host2,host5\targ2'
  tasks:
    - set_fact:
        my_data: "{{ my_data|default() +
                     [{'host': item.split(separator)[0].split(','),
                       'arg': item.split(separator)[1].split(',')}] }}"
      loop: "{{ db_lines }}"

gives

  my_data:
  - arg:
    - arg3
    host:
    - host6
    - host5
  - arg:
    - arg1
    host:
    - host4
    - host3
  - arg:
    - arg2
    host:
    - host1
    - host2
    - host5

It should be trivial to use it in the loops.

Cheers,

  -vlado

The input data is not a fixed list but can be any number of lines returned by the database and registered by variable “command_result” as below":

`

  • name: “Play 1”
    hosts: localhost
    tasks:
  • name: “Search DB”
    command: > mysql --user=root --password=p@ssword deployment
    –host=localhost -Ns -e “SELECT dest_ip,file_dets FROM deploy_dets WHERE num LIKE ‘{{ CR_Number }}’”
    register: command_result
    `

Kindly suggest.

Can you suggest what is the issue with this code ?

- name: Add hosts
include_tasks: "{{ playbook_dir }}/gethosts.yml"
dest_ip: "{{ item.split('\t')[0] }}"
groups: dest_nodes
file_dets: "{{ item.split('\t')[1] }}"
ansible_host: localhost
ansible_connection: local
with_items: "{{ command_result.stdout_lines }}"

And below is my get_hosts.yml file

add_host:
name: "{{ item }}"
with_items: "{{ dest_ip.split(',') }}"