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).
[2] Robert Verspuy: Using Ansible to setup complex networkingRobert Verspuy: Using Ansible to setup complex networking