Access a puppet class variable dynamically

puppet

Is it possible to dynamically access a variable in a class? For example:

class namespace::hello() {
    $cow = "moo"
    $dog = "bark"
}

$dynamic = 'cow'
$value = $namespace::hello::[$dynamic]  # doesn't work

I'm doing this because I have classes defined with variables in them for each environment, e.g.:

class company::env::production {
    $dns = "1.2.3.4"
}

class company::env::office {
    $dns = "2.3.4.5"
}

Best Answer

I have found a nasty solution. I hope someone can give me a better alternative.

By using inline_template with scope.lookupvar, you can reference a dynamic variable:

inline_template("<%= scope.lookupvar('$namespace::hello::${dynamic}') %>")

Update

Because of the complexity of the solution, I just made a hack on top of that hack. I made a custom function that's does that one liner:

module Puppet::Parser::Functions
  newfunction(:config, :type => :rvalue) do |arguments|

    if arguments.size != 2
      raise(Puppet::ParseError, "config(): 2 args required)")
    end

    env = arguments[0]
    var = arguments[1]

    lookupvar("::company::env::#{env}::#{var}")
  end
end

And in your .pp:

$dns_server = config("production", "dns_server")
Related Topic