Header image for the post. Shows lines of Ansible task code in an artistic manner.

Creating /etc/hosts using Ansible’s lineinfile module

A common task one might want Ansible to perform is to create an /etc/hosts file. This is trivial using Ansible’s lineinfile module.

The problem

A question came up on Stack Overflow today (since removed) which I felt I could contribute to. The member wanted to know how to generate /etc/hosts using a MySQL database and a dynamic inventory script. I do not address the dynamic inventory aspects in this post, but producing /etc/hosts from an Ansible variable is quite trivial using the lineinfile module.

In the modern, connected, world we now live in, the need for servers and desktops to maintain their own lists of hosts in /etc/hosts is rarely required. DNS etc is all we need. Maintaining a hosts file is necessary when working on isolated networks with no DNS. I have plenty of experience doing this for my clients at Discreet Information Technology Services.

The solution – Ansible’s lineinfile module

Unfortunately Ansible doesn’t have a built in module specifically designed to manage /etc/hosts but we can use Ansible’s lineinfile module to output lines to the hosts file. Perhaps I should write one?.

For demo purposes, the Ansible playbook extract I present below uses an inline task variable containing an array of dictionaries. This could also be located in the play variables, Ansible’s host vars file or the group vars file. Each dictionary in the array contains two keys ip and names. Needless to say ip contains an IP address and names is an array of host names for the associated IP address.

- name: add a list of hosts to /etc/hosts
  become: yes
  lineinfile:
    dest: /etc/hosts
    regexp: "^{{ item['ip'] }}.*$"
    line: "{{ item['ip'] }}\t\t{{ item['names'] | join(' ') }}"
    state: present
  with_items:
  - ip: 1.2.3.4
    names:
    - server1
  - ip: 4.5.6.7
    names:
    - server2a
    - server2b

We start by setting the destination file – /etc/hosts, define a regular expression that matches the format of the line we are planning on outputting so we can delete them later, the format of the line we want added to the file, in this case using a Jinja template, and finally make sure the line is present using the state: present option. The output for this task will be lines added to the hosts file in the following format:

1.2.3.4        server1
4.5.6.7        server2a server2b

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.