Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have a Puppet class that sets up a number of services and configuration files. In most cases, there is a default server that can be used, but it is also possible to configure explicit per-service servers. I find myself doing this all the time:

class myclass (
  $default_server    = '',
  $server_for_thing1 = undef,
  $server_for_thing2 = undef,
  $server_for_thing3 = undef
) {

  if $server_for_thing1 {
    $real_server_for_thing1 = $server_for_thing1
  } else {
    $real_server_for_thing1 = $default_server

  # ...and so forth...

As the number of possible services grows large, this syntax becomes unwieldy. Is there a better way of doing this? I really want something along the lines of:

$server_for_thing1 = $server_for_thing1 || $default_server

...but variables cannot be re-assigned in Puppet. Are there better ways of doing this?

share|improve this question

While not exactly what you are asking for, have you considered using an External Node Classifier to set and override the default value for specific servers? I believe the ECN is the "puppet way" of doing things in a situation like yours.

EDIT: (based on the first comment)

Second idea: you can use a custom function to at least make the multi-line repeated logic a bit more readable. Something like this, which returns the first "defined" argument, though with puppet, I am never sure what "defined" is (in this case, "undef" gets passed as an empty string to the function, which is still good enough).

module Puppet::Parser::Functions
    newfunction(:get_default, :type => :rvalue) do |args|
        value = nil
        args.each { |x|
            if ! x.nil? and x.length > 0
                value = x
        return value

You can then call it as many times as you want:

$real_server_for_thing1 = get_default($server_for_thing1, $default_server)
$real_server_for_thing2 = get_default($server_for_thing2, $default_server)
$real_server_for_thing3 = get_default($server_for_thing3, $default_server)
share|improve this answer
An external node classifier isn't going to be the right solution here, because this is not typically something that varies from node to node. It is more typically something in a generally reusable module that would vary from site to site. – larsks May 27 '12 at 0:55
Well, you could also set up a custom puppet function to shorten the three lines into one. Though I don't think that's what you are aiming for either. $real_server_for_thing1 = get_default($server_for_thing1, $default_server). get_default should return the second parameter if the first one is undefined (or empty, or null, because puppet's interpretation of "undef" is not always consistent). – chutz May 27 '12 at 7:01
I was actually thinking about doing exactly that (creating a custom function). And yeah, I've run into puppet's inconsistent treatment of undef. – larsks May 27 '12 at 11:40

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.