how to properly take care of network interfaces configuration file using Ansible?

Viewed 2752

I want to be able to fully manage my /etc/network/interfaces.d/ configuration files using Ansible.

I already use ansible for a lot of feature, including apache files, database, and logs files, but I can't find a way to properly add / update / remove network interface configuration files.

There are a few different project on my server using different interfaces, and I want my ansible to be able to work on any server i could deploy my project.

I already found a way to create a new file using the next free interface like this :

- name: calc next free interface
    set_fact:
      nextFreeIf: "
      {%- set ifacePrefix = vars.ansible_default_ipv4.alias -%}
      {%- set ifaceNum = { 'cnt': 0 } -%}
      {%- macro increment(dct, key, inc=1)-%}
        {%- if dct.update({key: dct[key] + inc}) -%}
        {%- endif -%}
      {%- endmacro -%}
      {%- for iface in ansible_interfaces|sort -%}
        {%- if iface| regex_search('^' ~ vars.ansible_default_ipv4.alias) -%}
          {{ increment(ifaceNum, 'cnt') }}
        {%- endif -%}
      {%- endfor -%}
      {{ifacePrefix}}:{{ifaceNum.cnt}}"
    tags: network

- name: "copy network interface configuration"
  template:
    src: "files/etc/network/interfaces.d/my-configuration.conf"
    dest: "/etc/network/interfaces.d/my-configuration.conf"
    owner: root
    group: root
    force: true
  notify: 'restart failover interface'
  tags: network

Now I need to find a way to check if my configuration file is already present so i don't recreate a new configuration file every time I run ansible. But if it is present, there is still a problem :

network configuration file will look like this

auto {{ interface }}
iface {{ interface }} inet static
    address {{ ip }}
    netmask 255.255.255.255

Since I don't know which interface is used by my project, I need to check for every available interfaces if it matches the actual file, and update using the next free interface if not.

I can't find a way to do it using Ansible!!

I hope you can help me.

2 Answers

Well, I found a nice way to do what I wanted:

I couldn't figure out what interface was in use, if so. That's why I wanted to check for every interfaces if they were the good ones. And I was trying to find this out by comparison between the file I would get for each interface and the existing file.

But I know which ip address is used, or will be used. Ansible has a fact for every interfaces in which I can find what address is corresponding. So I don't need to compare files, I only need to compare addresses.

I simply updated the task I used for getting the next free interface, to get the actual interface to use, which can be the next free interface, or the one already in use.

- name: find interface to use
  set_fact:
    interface: "
    {%- set ifacePrefix = vars.ansible_default_ipv4.alias -%}
    {%- set ifaceNum = { 'cnt': 1 } -%}
    {%- macro increment(dct, key, inc=1)-%}
        {%- if dct.update({key: dct[key] + inc}) -%}
        {%- endif -%}
    {%- endmacro -%}
    {%- for iface in ansible_interfaces|sort -%}
        {%- if ifacePrefix + '_' + ifaceNum.cnt|string in ansible_interfaces -%}
            {{ increment(ifaceNum, 'cnt') }}
        {%- endif -%}
    {%- endfor -%}
    {%- for iface in ansible_interfaces|sort -%}
        {%- if iface.startswith(ifacePrefix) and ansible_facts[iface]['ipv4']['address'] == ip_failover -%}
            {{ ifaceNum.update({'cnt': iface.split('_')[-1]}) }}
        {%- endif -%}
    {%- endfor -%}
    {{ifacePrefix}}:{{ifaceNum.cnt}}"
  tags: network

For information, the first for loop is getting the first free interface even when there is gaps in interface numbers which can happen when someone down some interfaces.

Related