Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

Generally when working with complex puppet modules, I will set variables at the node level or inside a class. e.g.,

node 'foo.com' {
  $file_owner = "larry" 
  include bar 
}

class bar { 
  $file_name = "larry.txt"
  include do_stuff
}

class do_stuff {
  file { $file_name:
    ensure => file,
    owner  => $file_owner,
  }
}

How/when/why does parametrized classes help when this situation? How are you using parameterized classes to structure your puppet modules?

share|improve this question
    
You spelled parameterized wrong. I would edit but I don't have enough rights or enough characters to change to permit a moderated edit. –  Kev Feb 27 '11 at 1:19
1  
Note to all who find this example, this code shows global variable lookups that were allowed in Puppet version < 3.0. In Puppet > 3.0, you cannot access variables out of scope, and must use namespace to access variables. In this example, you would have to use $bar::file_name and $::file_owner to access those respective variables. However, when using parametrized classes, the variables passed into a class via the parameters become locally scoped variables. –  robbyt May 11 '13 at 16:49
add comment

2 Answers

up vote 12 down vote accepted

Parameterized classes are a language construct to help you structure your code better. It prevents you from excessively using global variables (like in your example).

Imagine you included 20 more classes in your node description and all would need some variables being set in the manifest's global or node scope. Also parameterized classes allow you to have default parameters easily, so you could use a default value for the $file_owner instead of having to provide the same value (e. g. larry) in several different places.

Your example snippet (with two additional nodes) could be written as follows:

node 'example.com' { 
  class { bar: }
}

node 'example.net' {
  class { bar: owner = "harry" }
}

node 'example.net' {
  class { bar: file_name = "barry.txt" }
}

class bar($owner = "larry", $file_name = "larry.txt") { 
  class { do_stuff: owner => $owner, file_name => $file_name }
}

class do_stuff($owner, $file_name) {
  file { $file_name:
    ensure => file,
    owner  => $owner,
  }
}

With your usage of global variables, you'd need to declare a variable named $owner in each node and you would not be able to overwrite the $file_name variable/parameter per node. Instead you'd need to declare another bar class for each node.

The document on Puppet's language evolution and of course the language guide provide some good examples on how to use parameterized classes and the rationale behind this language construct:

share|improve this answer
    
great example, thank you! –  robbyt Feb 28 '11 at 3:52
add comment

Best way to think about this is to come at it from the beginning instead of starting with already knowing the Puppet idioms.

What you're trying to do in the first place is pass parameters into a class — you're giving it information it needs in order to decide how to behave, just like passing arguments to a function. Say this was perl and you had a function called multiply_squares. You'd call it like multiply_squares(3, 4), not set some global variables to 3 and 4 and then read them from inside the function!

But historically, Puppet code has had to do that with global variables or dynamic scope, because the need to do it arose before the language was designed to do it. Personally, I think once parameterized classes get a bit more evolved and more widely-deployed, they'll basically make variable scope issues a thing of the past, because having the right tool available for the job will eliminate a whole layer of frightening hacks.

share|improve this answer
    
You're right, controlling logic via global variables seemed a bit hack-ish in the past. This feature may be the motivation I need to finally refactor my (unwieldy...) puppet infrastructure. –  robbyt Feb 28 '11 at 3:55
add comment

Your Answer

 
discard

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.