I am writing a keepalived module for puppet. It will naturally be called: “puppet-keepalived”, and I will be releasing the code in the near future! In any case, if you’re familiar with VRRP, you’ll know that each managed link (eg: resource or VIP) has a common routerid and password which are shared among all members in the group. It is important that these parameters are unique across the type definitions on a single node.
Here is an example of two different instance definitions in puppet:
keepalived::vrrp { 'VI_NET': state => ..., routerid => 42, # must be unique password => 'somelongpassword...', } keepalived::vrrp { 'VI_DMZ': state => ..., routerid => 43, # must be unique password => 'somedifferentlongpassword...', }
Here puppet guarantees that the $name variable is unique. Let’s extend this magic with a trick to make sure that routerid and password are too. Here is an excerpt from the relevant puppet definition:
define keepalived::vrrp( $state, ... $routerid, $password ) { ... file { "/etc/keepalived/${instance}.vrrp": content => template('keepalived/keepalived.vrrp.erb'), ... ensure => present, # NOTE: add unnecessary alias names so that if one of those # variables appears more than once, an error will be raised. alias => ["password-${password}", "routerid-${routerid}"], } ... }
As you can see, multiple alias names are specified with an array, and since this file definition is used for each keepalived::vrrp instance, you’ll most assuredly cause a “duplicate alias” issue if there is a duplicate routerid or password used!
This trick will also probably work across define types too. To ensure a common key, just create an object like:
file { '/root/the_unique_key': alias => ["token1-${token1}", "token2-${token2}", "token3-${token3}"], }
The token prefix will guarantee that you don’t accidentally cause a collision between dissimilar parameter values, unless that’s what you want. I’ve used a file in this scenario, but you can use whatever object you like. Because of this reason, it would make sense to create a noop() type if you’re really serious about this. Maybe puppet labs can add a built-in type upstream.
This is the type of thing that’s important to do if you want to write puppet code that acts less like a templating hack and more like a library :)
Happy hacking!
James