switching from dhcp to static IP via Ansible


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
  net_interfaces: [ 'enp3s0' ] 

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

  - name: install needed network manager libs
    yum: name={{ item }} state=installed
    - 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 

  - 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 
              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
IPADDR="{{ host_sh.stdout }}"
NETMASK="{{ ansible_default_ipv4.netmask }}" 
GATEWAY="{{ ansible_default_ipv4.gateway }}" 
NAME="System enp3s0"

and the template for /etc/resolv.conf

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

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.


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

1 thought on “switching from dhcp to static IP via Ansible

  1. Why are you requiring network management packages when you are not using them?

    To modify just the conf files vi your templates and run a shell command you only need the bare minimums of Ansible.

Leave a Comment

%d bloggers like this: