Is it possible to declare variable in node and than propage it way down to the erb template?
Example:
node basenode {
$myvar = "bar" # default
include myclass
}
node mynode extends basenode {
$myvar = "foo"
}
class myclass {
file { "/root/myfile":
content => template("myclass/mytemplate.erb")
ensure => present,
}
}
Source of mytemplate.erb:
myvar has value: <%= myvar %>
I know that my example might be complicated. But I'm trying to propagate file on (almost) all my nodes and I want its content to be altered depending on the node which requests the file. The $myvar = "bar"
statement should be default when node does not override its value.
Is there a solution to my problem? I'm using puppet 0.24.5
Edit: The problem here is probably variable inheritance order. This $myvar variable won't have foo value in mynode node. The solution here would be to include myclass directly in mynode. But I really don't want to do that. Is there an option to override class variable value after the class has been included?
Puppet node inheritance is not the same as inheritance in most other programming languages . Included classes are evaluated immediatelly when the child is evaluated. And the parent node is evaluated after that. Therefore my example will never work. If you want to know recommended solution for this, read puppet - common misconceptions. I did it this way and it works.
Although I have to admit that I'm pretty disappointed right now, because complex puppet syntax might be confusing for starters.
Other answers have already pointed out the scoping problem. What you probably want to do is use the base node only for variable definitions, and separate out the actual logic (including your base class definitions) into a separate class that's included by all of your nodes. This preserves the scoping the way that you want, and only adds a single extra line to all of your node definitions.
Instead of declaring the default value within basenode, I would declare the default within the template itself. Since ERB is largely based on ruby, you can get away with some fairly extensive logic. Here is an example from the template I use for managing the snort config file.
In this case I am using an array that, if it exists, gets turned into a comma separated list for inclusion. Otherwise the default $HOME_NET gets used. If we simplify it to your example we could use:
Again, if the variable
myvar
has been set then that will be expanded, otherwise the string "bar" will be printed. This way the variablemyvar
can be set, or not, in your node definitions with impunity.