ansible update /etc/hosts file with IP of all hosts across all hosts - Middleware Inventory (2022)

In Ansible, SSH Communication is everything. Let it be connecting to remote servers from your controller laptop/desktop (mac/windows) or to enable connectivity between servers on the host group.

Especially this will be a huge task to accomplish when you do not have a DNS where each remote host can easily look up the IP of another host.

We all create so many instances in the cloud or in local vagrant for our task or testing, and how we can make them talk to each other and make them be aware of each other.

Let us pretend that we are working on a local environment setup using VAGRANT and trying to build three nodes and build SSH communication between them as well as SSH Key-based authentication.

In order to do that. We need to perform two tasks

  1. Making sure that each server is aware of the other server’s IP address in the host group and could resolve the IP using the hostname
  2. Exchange the SSH public key between each other.

The First and primary step is the whole objective of this post. The second item is already covered in my another post Enable SSH Authentication between remote hosts

Let us proceed.

The Pictorial representation of what we are trying to achieve is given above. Hope it makes sense.

Table of Contents

Domain Name Resolution or DNS Lookup

As mentioned earlier, if you are at industrial infrastructure with internal DNS available.

Each server you provision will have an entry in there and you should be able to resolve an IP andperform DNS lookup across the hosts you provision in your infrastructure with no further hurdles.

But in the local environmental setup like VAGRANT with NO dedicated DNS server. Or if you are not having any internal DNS system.

There is no option other than placing an entry manually into /etc/hosts file ( I presume you are aware of this file and what it does).

We call it a Local DNS lookup or First level DNS lookup. This helps me achieve the same thing that external DNS does.

So what we are trying to do here is that.I should be able to resolve the IP of all other hosts from the server I am trying without a DNS server in place

Practical Implementation/Example

I have three hosts newly built and named as follows

  • mwivmapp01 (192.168.16.11)
  • mwivmapp02 (192.168.16.12)
  • mwisqldb01 (192.168.16.13)

To enable communication between them and to transfer files between these remote server, I should be able to resolve the IP of all other hosts from the server I am trying.

For Instance, Frommwiapp01If Inslookupmwiapp02 and mwiapp03. I should get their corresponding IP address resolved the important thing here is that we have to do it with out DNS server in place.

So we need to make an entry using in /etc/hosts of all servers with other server IP and hostnames

Let us look at the before and after snapshots of /etc/hosts file of each individual host/server for more clarity before implementing.

Before /etc/hosts file update

After /etc/hosts/ file update ( Expected Result )

Here, you can see All the servers have their fellow group member’s IP addresses including their own. Thanks to Jinja2 and variables of Ansible.

Playbook to make an entry of all server IPs across all the servers in the hosts file.

This Playbook given here is generic. It will work for any number of servers as long as they are in the same host group.

All you have to do is change the host group from multi to whatever you are going to use. ( in two places)

--- - name: host file update - Local DNS setup across all the servers hosts: multi gather_facts: yes tasks: - name: Update the /etc/hosts file with node name tags: etchostsupdate become: yes become_user: root lineinfile: path: "/etc/hosts" regexp: ".*\t{{ hostvars[item]['ansible_hostname']}}\t{{ hostvars[item]['ansible_hostname']}}" line: "{{ hostvars[item]['ansible_env'].SSH_CONNECTION.split(' ')[2] }}\t{{ hostvars[item]['ansible_hostname']}}\t{{ hostvars[item]['ansible_hostname']}}" state: present backup: yes register: etchostsupdate when: ansible_hostname != "{{ item }}" or ansible_hostname == "{{ item }}" with_items: "{{groups['multi']}}"

For AWS EC2 instances – To Exchange the Private IP between hosts

The following snippet is designed to exchange the private IP address of host group members. this example is most suitable when you want to use the private IP address while updating the/etc/hostsfile

- name: Update the /etc/hosts file with node name tags: etchostsupdate become: yes become_user: root lineinfile: dest: "/etc/hosts" regexp: ".*\t{{ hostvars[item]['ansible_hostname']}}\t{{ hostvars[item]['ansible_hostname']}}" line: "{{ hostvars[item]['ansible_default_ipv4']['address'] }}\t{{ hostvars[item]['ansible_hostname']}}\t{{ hostvars[item]['ansible_hostname']}}" state: present backup: yes register: etchostsupdate when: ansible_hostname != "{{ item }}" or ansible_hostname == "{{ item }}" with_items: "{{groups['launched']}}"

For AWS EC2 instances – To Exchange the Public IP between hosts

While Private IP addresses are merely for internal communication. we might sometimes need to do the same task of/etc/hostsfile update amongst the host group members with public ip addresses

Let’s suppose you have a few AWS EC2 instances and you are trying to connect to all of them from your local machine and you want all of these EC2 instances to talk to themselves over public IP, Then this is for you.

the EC2 instance would not be aware of its public IP so there would be no public IP related references on the Ansible Facts or variables. The only way to determine the public IP is to rely on the ansible_hostsfile.

So this method would work only if you are using the Public IP to connect to the remote hosts from the control machine. In other words, Public IPs should have been used for this type to work.

- name: Update the /etc/hosts file with node name tags: etchostsupdate become: yes become_user: root lineinfile: dest: "/etc/hosts" regexp: ".*\t{{ hostvars[item]['ansible_hostname']}}\t{{ hostvars[item]['ansible_hostname']}}" line: "{{ inventory_hostname }}\t{{ hostvars[item]['ansible_hostname']}}\t{{ hostvars[item]['ansible_hostname']}}" state: present backup: yes register: etchostsupdate when: inventory_hostname != "{{ item }}" or inventory_hostname == "{{ item }}" with_items: "{{groups['launched']}}"

See it in Action

As said earlier, this is a First Step of enabling an SSH Key-based authentication between remote hosts.

The Next step is to exchange the key between remote servers so that Passwordless SSH Key-based authentication can be achieved. Continue to read, Enable SSH Authentication between remote hosts

Hope this helps.

Cheers,
Sarav AK

ansible update /etc/hosts file with IP of all hosts across all hosts - Middleware Inventory (4)

Follow us onFacebook orTwitterFor more practical videos and tutorials. Subscribe to our channelFind me on Linkedin My ProfileFor any Consultation or to hire us [emailprotected]If you like this article. Show your Support! Buy me a Coffee.

Signup for Exclusive "Subscriber-only" Content

More from Middleware Inventory

  • How to Copy files between remote hosts in ansible

    How to copy files between remote servers in Ansible ?. is the purpose behind this article. Every article I went and read was giving me suggestions but nothing practical. I simply wanted to do make ansible rsync. I wanted to execute rsync between remote hosts and copy files between remote…

  • ansible search for string in file or check if string exists in file

    The Objective of this post is to show how to search for a string in a file with ansible. ansible provides various ways to accomplish the same. We will cover, three major ways to search for a string in a file. Lineinfile module Using the Shell module and grep command…

  • Ansible get ip address of current host or target

    How to get the IP address of the current or remote host in Ansible. That's the question, this article is going to address. While running a Playbook you might have had a requirement where you need to get the IP address of the connected and current remote host. There are…

  • Ansible replace line in file - Ansible Replace Examples | Devops Junction

    This article is about "how to replace a line in file using ansible and seeing various other examples of ansible replace module". Ansible facilitates us with a dedicated module named as replaceThe working principle of this module is more like find and replacein your favourite editor and it also supports…

  • Ansible Command Module Examples

    Ansible Command Module Introduction Ansible Command module is used to execute commands on a remote node. The Command module, is used mostly to run simple Linux commands on a remote node/server which is part of a host group or Stand alone server mentioned in the host group. If you want…

Top Articles

Latest Posts

Article information

Author: Stevie Stamm

Last Updated: 10/11/2022

Views: 6521

Rating: 5 / 5 (60 voted)

Reviews: 83% of readers found this page helpful

Author information

Name: Stevie Stamm

Birthday: 1996-06-22

Address: Apt. 419 4200 Sipes Estate, East Delmerview, WY 05617

Phone: +342332224300

Job: Future Advertising Analyst

Hobby: Leather crafting, Puzzles, Leather crafting, scrapbook, Urban exploration, Cabaret, Skateboarding

Introduction: My name is Stevie Stamm, I am a colorful, sparkling, splendid, vast, open, hilarious, tender person who loves writing and wants to share my knowledge and understanding with you.