ip_link_device now supports bonds

George Shuklin
OpsOps
Published in
2 min readFeb 3, 2021

I’ve just updated collection amarao.ip with new version of module ip_link_device. Now it supports type=bond interfaces.

WTF is amarao.ip?

It’s my Ansible collection (if you’ve missed, Ansible upgraded it’s galaxy options with a new way to distribute modules, it’s called ‘collections’) with modules to work with ‘ip’ utility. It allows to create, update attributes and delete network interfaces, manage IP addresses, etc.

Screenshot from Ansible Galaxy

Why?

There is no standard module to manage network stack in Ansible. There are modules to manage configs for ifupdown, it’s possible to template config files for netplan and CentOS network scripts, but they all:

  1. Persistent (which not always desired).
  2. Require a lot of work.
  3. Hard to work in snippet mode (‘add a little more to existing configuration’), which is often the case for the cloud instances.

The ugly solution to this is command module to work with ip, but it’s really hard to make it right. To provide idempotency and convergence one needs to query each object and use when for command invocation. If you need to configure two veth interfaces into two different namespaces with IP addresses, it’s about 14 tasks al least: (create, move to namespace x2, bring up x2, add interface x2) x 2

A module is much easier to use.

Here is the single module invocation for aforementioned big tasklist:

- name: Configure veths
amarao.ip.ip_link_device:
name: veth33
type: veth
ns: myns1
veth_options:
peer_name: veth99
peer_ns: myns2
state: present

So, bond?

Yes, I’ve added type: bond support. It was hard. First, man ip link lacks section for bonding interfaces. :-/ Second, there are 26 different options and parameters for bond to create. Some of them are tricky to work with as they don’t follow normal convention for command line parameters.

All together it leaded me to more than 400 lines MR (most of it are docs).

The usual 802.3ad style bonding looks like this:

- name: Create bond
amarao.ip.ip_link_device:
name: bond0
type: bond
bond_options:
mode: 802.3ad
xmit_hash_policy: layer2+3
lacp_rate: fast
state: present
- name: Assign interfaces to bond
amarao.ip.ip_link_device_attribute:
name: '{{ item }}'
master: bond0
loop: [eth0, eth1, eth2, eth3]
- name: Bring bond up
amarao.ip.ip_link_device_attribute:
name: bond0
state: up
- name: Assign IP to the interface
amarao.ip.ip_address:
name: bond0
address: 192.168.42.42/24

Now ip_link_device supports most of the major software-defined interface types: vlans, vxlans, bridges, bonds, gre. And few rare but easily implementable (like ‘dummy’).

If you miss some additional types, just open issue in the repo’s issue tracker.

How to use it?

Generally, you need to known how to use external collections.

After that it’s simple as

ansible-galaxy collection install amarao.ip

You can use

ansible-doc -t module amarao.ip.ip_link_device
ansible-doc -t module amarao.ip.ip_link_device_attribute
ansible-doc -t module amarao.ip.ip_address

to see all module options.

--

--

George Shuklin
OpsOps

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