Sysadmin stories

Ramblings about my job and trade

A Puppet Module for Managing BIRD

Do you know the BIRD Internet Routing Daemon? If not, and if you have any kind of need for dynamic routing, you should probably have a look at it. From my experience, its OSPF implementation is at least much more stable than the one in Quagga. Now, I needed a Puppet module to manage it, didn’t I?

Existing choices

“Existing” is probably at least a bit misleading here, as the only other module I am aware of hadn’t been published yet when I began writing my own (actually I just discovered its existence 10 minutes ago).

From a cursory glance at Sebastien’s code, I quite like his idea of invoking birdc and birdc6 directly for restarting his services. However his module does not manage the configuration files at all; mine does and the feature gets real-life use.

So where is the code?

Here. The module code itself probably does not comply fully with the GPL at the moment (it is missing the legalese in headers); I expect to fix it as soon as I can find some time. I also expect to advertise it on Puppet Forge as soon as I add the missing bits (Modulefile and so on).

At the moment this module is running in production on a couple CentOS 5 hosts with custom-built BIRD packages; it should also work on recent enough versions of Debian (“recent enough” meaning Jessie). The situation is a bit more complicated with Wheezy; basically, package bird 1.4.0-1~bpo70+1 from Wheezy backports includes both bird and bird6 daemons, whereas package bird 1.3.7 from Wheezy itself only installs the IPv4 version but recommends the IPv6 package. The Puppet module installs package bird only; it should work if the package drags the bird6 daemon along with it.

OK, this was the code, now what?

What about the docs?

Seems like I’m writing them right now. :–)

The most basic use is probably the obvious one:

include bird

This will give you working instances of bird and bird6 which do, well, basically nothing. If you want them to do something, you can add config snippets in /etc/bird.conf.d/ and /etc/bird6.conf.d/ directories and restart the daemons (kill -HUP will do).

What if for some reason you don’t want both protocols? Simple enough, you can disable the useless one:

class { 'bird':
  enable_ipv4 => false,

By default, the “main” IP address of the host (that is, the one returned by the fact ipaddress) is used as the router ID. You can of course change this:

class { 'bird':
  router_id => '',

There are also a couple defines for generating some of those configuration snippets I was talking about a bit earlier. For instance, you can add an OSPF instance:

bird::protocol::ospf { 'VPNv4':
  ip_protocol     => 'ipv4',
  ospf_interfaces => {'eth0' => {password => $eth0_ospf_password},
                     {'eth1' => {password => $eth1_ospf_password},
                     {'eth2' => {}}},
  stub_interfaces => 'tap0',

Or set up RAdv on an IPv6 interface:

$radv_prefixes = { "$vpn_interface" => $ipv6_subnet }
class { 'bird::protocol::radv':
  prefixes => $radv_prefixes,

Basically, these defines are enough for my real-life use cases. If anything more specific is needed, I can just craft a snippet by hand and add it to the configuration directories.

What next?

The basic functionality is here. The module itself, on the other hand, is missing quite a lot of things, including documentation and tests.

Maybe adding simple BGP support would be a good idea too; I don’t need it right now but who knows?

And, of course, publishing the module on the PuppetLabs Forge should come as soon as possible. I’ll let you know. ;–)