Creating /etc/hosts from ansible hosts

I am trying to figure out if there is a way to use Ansible to automate the creation of /etc/hosts files depending on which group the Ansible host belongs to. I am creating multiple test Kubernetes clusters that will use hosts files for DNS resolution.

`

[Group 1]
kube-g1-master1 ansible_host=10.90.1.11
kube-g1-master2 ansible_host=10.90.1.12
kube-g1-master3 ansible_host=10.90.1.13
kube-g1-node1 ansible_host=10.90.1.14
kube-g1-node2 ansible_host=10.90.1.15
kube-g1-lb ansible_host=10.90.1.16
[Group 2]
kube-g2-master1 ansible_host=10.90.1.21
kube-g2-master2 ansible_host=10.90.1.22
kube-g2-master3 ansible_host=10.90.1.23
kube-g2-node1 ansible_host=10.90.1.24
kube-g2-node2 ansible_host=10.90.1.25
kube-g2-lb ansible_host=10.90.1.26
[Group 3]
kube-g3-master1 ansible_host=10.90.1.31
kube-g3-master2 ansible_host=10.90.1.32
kube-g3-master3 ansible_host=10.90.1.33
kube-g3-node1 ansible_host=10.90.1.34
kube-g3-node2 ansible_host=10.90.1.35
kube-g3-lb ansible_host=10.90.1.36
etc…

`

When I use [all], as Ansible iterates through the hosts file can it search which Group the host belongs to and create an /etc/hosts from the group hostnames and IPs.

For example:

  1. Ansible interacts with: kube-g2-master3

`
inventory_hostname = kube-g2-master3

`

  1. Finds kube-g2-master3 belongs [Group 2]

  2. Creates /etc/hosts on kube-g2-master3 using the inventory_hostname and ansible_hosts from [Group 2]

`
/etc/hosts

kube-g2-master1 10.90.1.21
kube-g2-master2 10.90.1.22
kube-g2-master3 10.90.1.23
kube-g2-node1 10.90.1.24
kube-g2-node2 10.90.1.25
kube-g2-lb 10.90.1.26

`

Thanks for any help.

I am trying to figure out if there is a way to use Ansible to automate the
creation of /etc/hosts files depending on which group the Ansible host
belongs to. I am creating multiple test Kubernetes clusters that will use
hosts files for DNS resolution.

[Group 1]
kube-g1-master1 ansible_host=10.90.1.11
kube-g1-master2 ansible_host=10.90.1.12
kube-g1-master3 ansible_host=10.90.1.13
kube-g1-node1 ansible_host=10.90.1.14
kube-g1-node2 ansible_host=10.90.1.15
kube-g1-lb ansible_host=10.90.1.16
[Group 2]
kube-g2-master1 ansible_host=10.90.1.21
kube-g2-master2 ansible_host=10.90.1.22
kube-g2-master3 ansible_host=10.90.1.23
kube-g2-node1 ansible_host=10.90.1.24
kube-g2-node2 ansible_host=10.90.1.25
kube-g2-lb ansible_host=10.90.1.26
[Group 3]
kube-g3-master1 ansible_host=10.90.1.31
kube-g3-master2 ansible_host=10.90.1.32
kube-g3-master3 ansible_host=10.90.1.33
kube-g3-node1 ansible_host=10.90.1.34
kube-g3-node2 ansible_host=10.90.1.35
kube-g3-lb ansible_host=10.90.1.36
etc...

When I use* [all]*, as Ansible iterates through the hosts file can it
search which Group the host belongs to and create an* /etc/hosts* from the
group hostnames and IPs.

Space in group names is not allowed.

For example:

1. Ansible interacts with: *kube-g2-master3*

inventory_hostname = kube-g2-master3

2. Finds *kube-g2-master3* belongs* [Group 2]*

Groups in Ansible is just for grouping variables, and the grouping is lost when Ansible is running.
What you can do is check if a host is in a group, but you would need to check every group.
   when: "'kube-g2-master3' in groups['group2']"

And the list of all group is in the special variable "group_names".

3. Creates */etc/hosts* on *kube-g2-master3* using the *inventory_hostname*
and *ansible_hosts* from* [Group 2]*

/etc/hosts

kube-g2-master1 10.90.1.21
kube-g2-master2 10.90.1.22
kube-g2-master3 10.90.1.23
kube-g2-node1 10.90.1.24
kube-g2-node2 10.90.1.25
kube-g2-lb 10.90.1.26

Since you are building a host list, all you need in the variable groups['group2'] this is a list of all members in that group.

Use "group_names: List of groups the current host is part of"
https://docs.ansible.com/ansible/latest/reference_appendices/special_variables.html

It's possible to create lists of [host, ip]. For example (given a host may be
a member of multiple groups) the tasks below

  - set_fact:
      my_hosts: "{{ my_hosts|default() +
                    groups[item]|
                    zip(groups[item]|
                    map('extract', hostvars, 'ansible_host')|list)| list }}"
    loop: "{{ group_names }}"

    - set_fact:
        my_hosts: "{{ my_hosts|unique }}"

give

    "my_hosts": [
        [
            "test_01",
            "10.1.0.51"
        ],
        [
            "test_02",
            "10.1.0.52"
        ],
        [
            "test_03",
            "10.1.0.53"
        ]
    ]

Then create /etc/hosts. For example

    - template:
        src: hosts.j2
        dest: /tmp/hosts

  $ cat hosts.j2
  {% for item in my_hosts %}
  {{ item.0 }} {{ item.1 }}
  {% endfor %}

Cheers,

  -vlado