Automatic allocation of IP addresses in Ansible

George Shuklin
OpsOps
Published in
2 min readJun 11, 2018

I found myself a new challenge: to teach ansible how to automatically allocate IP addresses to all hosts in the specific group.

Background

I need to boot a test cluster installation. That cluster relies on using non-routable IP addresses for its cluster network. In production environment those IP addresses are provided by the special provision system which tracks and assigns/deassigns IP addresses. But in my laboratory environment the cluster network requires manual allocation of those pesky addresses in an inventory. So, my challange was to allocate those IP addresses automatically by Ansible.

I stitched together few nice features of Ansible, and here is the answer:

---
- hosts: localhost
gather_facts: no
tasks:
- fail:
msg: "Too many hosts ({{net | ipaddr('size') }} for {{net}}"
when: groups.all|length > net|ipaddr('size') - 2
- debug: msg='{{ item.1 }} - {{ (net|ipaddr(item.0 + 1)) }}'
with_indexed_items: '{{ groups.all }}'
vars:
net: 192.168.1.0/24

Explanation

  1. with_indexed_items creates sequence of items, where item.0 is a ‘sequence number’ of element in the list, and item.1 is the element itself. Please note, that ansible 2.5 wants you to use loop, statement, in this case, please use loop keyword and loop_control.index_var to get the index of the element.
  2. net is our target network.
  3. net|ipaddr(number) allocates IP address with number “number“ from net. We pass index of the element to this filter and get back ip address. F.e. element 0 will get IP address 192.168.1.0, an element 1 will get 192.168.1.1, etc. We use +1 here as we want to use IP 192.168.1.1 for the host number 0 in the list (192.168.0.0 is a network address, not a host address).
  4. We use fail module to stop execution if our request for IP allocation could not be satisfied. net|ipaddr(‘size’) returns theoretically possible number of addresses in the network. We substract 2 because 0 is a network address and last (.255) is a broadcast address.
  5. groups.all|length gives us number of hosts in the group “all”.

Conclusion

By using auto allocation of IP addresses I’ve significantly reduced size of the inventory to fill for each laboratory setup.

Warning

Please note, that this trick will fail if you change number of host after initial provision. It’s fine for laboratory use, but unsuitable for production.

--

--

OpsOps
OpsOps

Published in OpsOps

Tech blog on Linux, Ansible, Ceph, Openstack and operator-related programming

George Shuklin
George Shuklin

Written by George Shuklin

I work at Servers.com, most of my stories are about Ansible, Ceph, Python, Openstack and Linux. My hobby is Rust.