Since the error refers to file templates.pp rather than nodes.pp, I'm guessing that your class baseclass is getting evaluated before node 'hostname's node block. You don't show enough for me to be certain that's happening, but I suppose you also have something like
node basenode {
include baseclass
}
Node 'hostname' inherits from node basenode, so node basenode's node block is evaluated first, causing class 'baseclass' to be evaluated, which declares class abc::def without specifying a 'user' parameter.
Let me just say at this point that I would advise you to avoid node inheritance, or at most to use it sparingly. See
http://docs.puppetlabs.com/puppet/3/reference/lang_node_definitions.html#inheritance. If you must use node inheritance, then keep these things in mind:
- Each applicable node block is evaluated independently and therefore must stand on its own, except inasmuch as a child node can rely on its parent to be evaluated first. Inheritance is basically a chaining mechanism.
- In particular, node inheritance is not a mechanism for overriding declarations in the base node. It especially does not provide for overriding variable declarations in the parent node's scope, though you can shadow them by declaring a new variable of the same name in the child node. Doing so is highly inadvisable and unlikely to achieve what you want.
- Deep node inheritance trees are likely to get you into trouble.
- Class inheritance plays reasonably well with node inheritance when you want to perform some sort of overriding, but class inheritance for the purpose of overriding resources is out of favor. That's odd, really, because resource overrides are an essential part of the intended use for class inheritance. Now, the only use that's in favor involves the order-of-evaluation side effects of class inheritance.
I would recommend that you look into binding data to your class parameters via Puppet 3's hiera-based automated data binding facility, and avoid parameterized-style class declarations altogether. Really, it's the only mode in which I ever recommend using parameterized classes. It will get you around the issues you are having with the order of class declaration evaluation by allowing you to make all declarations of each class equivalent. That situation is one of the traditional strengths of Puppet's DSL, but it is broken by use of parameterized-style class declarations.
John