0
votes

In the setup I'm working the variable $var1 is declared in several places. However I'm not sure which line is last applied. The structure is as follows.

The puppet module, module1, contains a vars.pp class which is inherited by its init.pp manifest. In the vars.pp manifest var1 is declared as "value-vars".

#vars.pp
$var1 = "value-vars"

This module is applied to any node that matches a certain regex which is defined in the nodes.pp.

#nodes.pp
node "/nodepattern/" inherits base {
require module1
}

nodes.pp inherits from base.pp which declares var1 as "value-base".

#base.pp
$var1 = "value-base"

Now when the module is applied to a certain node, what value would var1 contain?

Is it "value-vars" because node block is applied before the class?

UPDATE

├── puppet3
│   ├──**manifests**
│   │   └───**nodes**
│   │     └──base.pp (node "base", $var1 = "value-base") 
│   ├──nodes.pp (various nodes inheriting base node, contains module1 node)
│   ├──**modules**
│   │    ├──**module1**
│   │    │    ├──**manifests**
│   │             ├──vars.pp (class "vars", $var1 = "value-vars")
│   │             ├──init.pp (class "module1", inherits vars class)
1
You could simply do notify {"value: ${var1}":} to show the value when testing with puppet agent -t or notice("value: ${var1}") to add the message to master's log - webNeat
Thanks for idea webNeat, but this particular setup is rather a complex one, a part of a cloud management code. To execute this I need to setup a lot of systems and nodes. I was looking for the theoretical explanation on this. - chamilad

1 Answers

0
votes

I sense some confusion here. A manifest cannot "inherit" another manifest. What's worse - from Puppet 4.0, a manifest file will not even be able to import another one.

This leaves scarce options to declare globally scoped variables. You should avoid declaring the same variable globally in different .pp files anyway, because any compilation that imports both files will fail!

Structure that works like "if this node includes module A, use value X for variable N" is tricky with Puppet. Manifests work best if there is one central piece of information that you can rely on, e.g.

node <long-cloud-instance-name-here> {
    $uses_app_foo = true
    $is_master_server = false
    include my_cloud_app
}

Both the decision to include module A and the assignment of X to N should then be based on those node scope variables.

This pattern gets old for large numbers of nodes. It is therefor advisable to devise a Hiera hierarchy that helps you define your node data with less redundancy.

Update

Seeing as you are using classes apparently, here are the additional rules that should make things clearer:

  1. a variable that is declared in the local scope (class or define body) hides variables from wider scopes that share its name
  2. a variable that is declared in the node block hides a global variables with the same name

Evaluation order does not come into play. The scoping rules always apply. Multiple assignments on the same scope are forbidden and lead to a compiler error. As you are not facing that scenario, the above rules do apply.

$foo = 'global'

# $foo == 'global'

node default {
    $foo = 'node'
    include bar
    # $foo == 'node'
}

class bar {
    $foo = 'class'
    # $foo == 'class'
    include baz
}

class baz {
    # foo == 'node' (!)
}