Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to enumerate hosts in ansible?

I am new to using Ansible and using it to automate the configuration of master slave node clusters.

I have a hosts file split into two groups:

[master]
masternode

[slaves]
slavenode0
slavenode1

What I would like to to is iterate through the slaves group such that a line in a file on the remote machine is updated with the index of the position in the slaves group.

When I tried to do this using 'with_items' or with 'with_indexed_items' the problem is that the file gets updated on each machine in the slaves group, corresponding to the amount of slavenodes in the slaves group. This means that every file on every slavenode ends up with exactly the same line inserted, just that the file was updated x times.

So I want:

| slave node | filename | line in file     |
| slave0     |  test    | slave index is 0 |
| slave1     |  test    | slave index is 1 |

What I got was:

| slave node | filename | line in file     |
| slave0     |  test    | slave index is 1 |
| slave1     |  test    | slave index is 1 |

Is there a way to achieve this?

like image 958
Aesir Avatar asked Dec 02 '22 11:12

Aesir


2 Answers

Edit
After re-reading your question, i think i had misunderstood it.

To get the index of the current host within an inventory group, you can use the index method on the groups list.

{{groups['slaves'].index(inventory_hostname)}}

Example

- lineinfile:
    path: ~/test
    line: "slave index is {{groups['slaves'].index(inventory_hostname)}}"


Original answer
If you use jinja2 templates with ansible you can access the index in a for loop with {{loop.index}}.

An example template for your slave configuration could be look like this

| slave node | filename | line in file |
{% for slave in groups['slaves'] %}
| {{slave}} | test | slave index is {{loop.index}} |
{% endfor %}

This should have the desired output

| slave node | filename | line in file |
| slavenode0 | test | slave index is 1 |
| slavenode1 | test | slave index is 2 |

To use this in your playbook you use the ansible template module.

tasks:
  - name: master slave configuration
    template: src=slave.conf.j2 dest=/etx/slave.conf
like image 172
lgraf Avatar answered Dec 22 '22 06:12

lgraf


you could run the play towards the localhost and when it comes to the lineinfile task, you should add the delegate_to option to run the task to each of the hosts.

You didnt include the lineinfile code, so i cant adjust it for you, but you can see example below that demonstrates how the index increments per host:

- name: Print index of each host
  shell: "wall 'this is iteration: #{{ index_no}}'"
  delegate_to: "{{ item }}"
  loop: "{{ groups['is_hosts'] }}"
  loop_control:
    index_var: index_no

hope it helps

like image 41
ilias-sp Avatar answered Dec 22 '22 05:12

ilias-sp