Meaningful hostnames with Ansible

Like anyone who spends a good deal of time in a terminal window, switching between machine instances is fairly commonplace. I keep a persistent tmux session open to manage a handful of connections.

Knowing which machine you're currently using is obviously imperative, but can be little challenging in highly dynamic environments like AWS.

I have implemented Ansible for managing configuration on a large number AWS instances. The following script applies a dynamic hostname to the instances based on a predefined prefix.

The playbook should look something like this:

- hosts: dev
  remote_user: user
  sudo: yes
  vars:
    env: dev
    hostname: dev-web-*
  roles:
    - common
    - supervisor

We will dynamically replace the ampersand * character with the tail of the host IP address. For our environment, hosts are commonly identified by their roles and the last /32 of the address within the current subnet.

We will add the following tasks to the common role:

# set the friendly hostname from the playbook variable
- name: set hostname
  hostname: name={{ hostname.replace('*', ansible_all_ipv4_addresses[0].split('.')[3]) }}

# add the new hostname to the hosts file
- name: add to hosts
  lineinfile: >
    dest=/etc/hosts
    regexp='^127\.0\.0\.1'
    line='127.0.0.1 localhost {{ hostname.replace("*", ansible_all_ipv4_addresses[0].split(".")[3]) }}'
    state=present

The hostname module will work for just about any distribution (in my case, Ubuntu) you might be using. Once you have run the playbook, your hostname should look something like:

ubuntu@dev-web-62:~$

The new hostname dev-web-62 is much more meaningful than the default hostname provided by EC2. You can use this same pattern to configure DNS for each instance, and update the tag Name for better readability in the AWS web console.