Overview

In my lab environment i want  to keep influencing dependencies low. While setting up the servers they got their ip address through dhcp. Now this will be switched to the static IP, which is found in DNS for this server.

ansible nmcli module

i played with ansible-nmcli module [1] but the resulting ifcfg-* file had a lot of directives i did not want and i was not able to set bootmode to static or set ipv6init to none. Also the netmask needed to be CIDR but i only had a 4-octet netmask available.

interface configuring through self provided templates

Secondly i set up templates and copied them over. This approach is much faster developed and much more flexible towards the personal needs. I must confess, i’m very much inspired from here [2], but it is over sized for my current my needs.

# cat /etc/ansible/set_ip.yml
# found debug here: 
# http://serverfault.com/questions/537060/how-to-see-stdout-of-ansible-commands
# https://github.com/ansible/ansible/issues/4317
# -v on command line would have worked as well

# found how to get the ip adress here:
# http://stackoverflow.com/questions/25410656/ansible-ip-address-variable-host-part

- hosts: servers
  vars: 
  net_interfaces: [ 'enp3s0' ] 

  tasks:
  - name: install bind-utils
    yum: name=bind-utils state=installed

  - name: install needed network manager libs
    yum: name={{ item }} state=installed
    with_items:
    - NetworkManager-glib
##    - libnm-qt-devel.x86_64
    - nm-connection-editor.x86_64
    - libsemanage-python
    - policycoreutils-python

# we asure name resolution before host lookup
  - name: Setup networking (resolv.conf)
    template: owner=root group=root mode=644 
              src=/etc/ansible/templates/resolv.conf 
              dest=/etc/resolv.conf

  - name: Get the host IP
    shell: host {{ ansible_fqdn }} | awk '{print $NF}' ; test ${PIPESTATUS[0]} -eq 0 
    register: host_sh
  - debug: msg="{{ host_sh.stdout }}"

  - name: Setup networking (interfaces)
    template: owner=root group=root mode=644 
              src=/etc/ansible/templates/ifcfg-interface 
              dest=/etc/sysconfig/network-scripts/ifcfg-{{ item }}
    with_items: "{{ net_interfaces }}"
 
 
  - name: Restart Network
    service: name=network state=restarted

Please recon the test-command behind the pipe-command of the shell:

   shell: host {{ ansible_fqdn }} | awk '{print $NF}' ; test ${PIPESTATUS[0]} -eq 0 

The test command reevaluates the return code of the first command of the pipe and delivers this as return code of the whole cmd-line.  This assures that Ansible will bail out, when there is a problem in name resolution.

The template for the interface configuration:

# cat /etc/ansible/templates/ifcfg-interface 
# configured via ansible
BOOTPROTO="static"
DEVICE="enp3s0"
ONBOOT=yes
TYPE=Ethernet
IPADDR="{{ host_sh.stdout }}"
NETMASK="{{ ansible_default_ipv4.netmask }}" 
GATEWAY="{{ ansible_default_ipv4.gateway }}" 
DEFROUTE=yes
PEERDNS=no
PEERROUTES=yes
DHCP_HOSTNAME=gluster12.example.com
IPV4_FAILURE_FATAL=no
IPV6INIT=no
NAME="System enp3s0"

and the template for /etc/resolv.conf

# cat /etc/ansible/templates/resolv.conf 
# configured by ansible
search example.com
nameserver 172.16.20.1

and the command to run the whole thing:

# ansible-playbook -v /etc/ansible/set_ip.yml

checking success

I also did some checks to assure things worked out:

# ansible -a "cat /etc/resolv.conf" servers
# ansible -a "cat /etc/sysconfig/network-scripts/ifcfg-enp3s0" servers
# ansible -a "ping -c 1 jump.example.com" servers

Note: Please be aware of “-c 1” for the ping command. As ping runs endlessly, the Ansible script never finishes. I find this hard to debug, so you might as well do it correctly in the first place.

Conclusion

This is a lightweight Ansible automation to switch to static IPs. Especially when dealing with or testing of outages etc. it might be beneficial, when IP communication is not based on dhcp (which might suffer outage as well).


[1]  nmcli – Manage Networking

[2] Robert Verspuy: Using Ansible to setup complex networkingRobert Verspuy: Using Ansible to setup complex networking