Announcing multi_epp - Puppet function

As part of refreshing my old puppet modules I’ve started to convert some of my Puppet templates from the older ERB format to the newer, and hopefully safer, Embedded Puppet (EPP).

While it’s been a simple conversion in most cases, I did quickly find myself lacking the ability to select a template based on a hierarchy of facts, which I’ve previously used multitemplate to address. So I wrote a Puppet 4 version of multitemplate that wraps the native EPP function, adds matching lookup logic and then imaginatively called it multi_epp. You can see an example of it in use here:

class ssh::config {

  file { '/etc/ssh/sshd_config':
    ensure  => present,
    mode    => '0600',
    # note the array of files.
    content => multi_epp( [
                            "ssh/${::fqdn}.epp",
                            "ssh/${::domain}.epp",
                            'ssh/default_sshdconfig.epp',
                          ], {
                                'port'          => 22222,
                                'ListenAddress' => '0.0.0.0',
                          }),
  }

}

This was the first function I’ve written using the new, Puppet 4 function API and in general it feels like an improvement to the previous API. The dispatch blocks and related functions encourage you to keep the individual sections of code quite small and isolated but will require some diligence to ensure you don’t duplicate a lot of nearly similar code between signatures. I also couldn’t quite do what I wanted (a repeating set of params followed by one optional) in the API but I’ve worked around that by requiring all the files to check be given as an array; which works but is a little icky. I’ve not gone full “all the shiny” yet and included things like function return values and types but I can see myself converting some of my other functions over to gain the benefit of easier parameter checking and basic types.

So what’s next on the path to EPP? For me it’ll be to get my no ERB template puppet-lint check running cleanly over a few local modules and to double check I don’t slip back in to old habits.