Thursday, 20 November 2014

Deploying Kamailio with Puppet

Almost three years ago I started automating the deployment
of all server-side applications with Puppet.

One of the key applications in Truphone's RTC platform (and arguably in
most of VoIP/WebRTC platforms today) is Kamailio,
so with some proper encapsulation it’s been possible to build a Puppet module
dedicated to it.

This is now publicly available on PuppetForge. Puppet Forge is a public
repository of Puppet modules. We use many of them, and they can be incredibly
useful to get you up to speed and solve common problems. You can also fork it on github, if you want.

You can use this module in different ways:

To quickly deploy a kamailio instance, with default
configuration files.

As the basis for a custom configuration, where you use
the official debian packages but with your own configuration details and
business logic.

The first approach is very simple. Imagine you start from
and empty VM or base docker container: all you have to do is install puppet,
download the trulabs-kamailio module from Puppet Forge and apply the test
manifest included in the module.

Dry-run the deployment with ‘noop’ first, and see what
Puppet would do:

$ puppet
apply -v /etc/puppet/modules/kamailio/tests/init.pp --noop

And then run it for real, by removing ‘noop’:

$ puppet
apply -v /etc/puppet/modules/kamailio/tests/init.pp

Now you can verify that Kamailio is running, listening on
the default interfaces, and at the latest stable version (this was tested on
debian wheezy, and it’s expected to work on Ubuntu Precise and Trusty too).

The second approach (using trulabs-kamailio as a basis for
your custom configuration) requires a little bit more work.

Here’s an example, where we want to deploy kamailio as
WebSocket proxy. What changes in respect to the test installation is:

We need to install also ‘kamailio-websocket-modules’ and
‘kamailio-tls-modules’ (as I’m assuming the WebSockets will be Secure).

Take care of the kamailio cfg files directly, and not use
the vanilla ones (trulabs-kamailio contains the “sample cfg files” already
available with the official debian packages).

A sensible approach is to create a new Puppet module, e.g.
‘kamailio_ws’, and inside its init.pp instantiate the ‘kamailio’ class with
these options:

You can see that ‘manage_config’ is set to false, which is
the way of telling the kamailio module not to install the vanilla cfg files,
and that those will be managed elsewhere (inside the kamailio_ws module in this
case).

To install your cfg files it’s sufficient to add something
like this to the init.pp manifest:

In this way you’re declaring that the kamailio.cfg file (to
be installed in /etc/kamailio/kamailio.cfg) has to be taken from the files/
folder inside the kamailio_ws module.

As an additional action, every time that file changes,
Puppet should notify the user that a restart is necessary (and then leave to
the sysadmin to choose the right moment to do so – the Exec resource is just
expected to print something on std out).

If you want to restart kamailio immediately after
kamailio.cfg changes, then you can use:

Note that if the file doesn't change, for example because
you’re just running Puppet to verify the configuration, or updating another
file, then Puppet won’t try any action associated to the ‘notify’ keyword.

You can then add all the other files you want to manage
(e.g. you may have a defines.cfg file that kamailio.cfg includes) by
instantiating other File resources.

A common practice for modules is to have the main class (in
this case kamailio_ws) inside the init.pp manifest, and the configuration part
(e.g. kamailio.cfg) inside a config.pp manifests included by init.pp.

What do you think? Would you like to see any particular
aspect of automating Kamailio configuration treated here? Will you try this
module?