Search code examples
puppet

Node specific settings in a puppet environment


I'm in the process of learning puppet and I'm running into what I assume is a pretty basic issue. For the purposes of keeping things simple, I'm using a puppet forge module rather than anything custom written. Here's what I'm using version wise:

puppet server: 5.1.3
puppet agent: 5.3.2
puppetlabs-java: 2.1.0

When I install the puppetlabs-java module, I am using --modulepath /etc/puppetlabs/code/modules/.

I currently have my agent configured to point at my puppet server and an environment I have named example.

The environment currently looks like this:

├── environment.conf
├── hiera.yaml
├── manifests
│   └── init.pp
└── modules
    └── java.pp

I have done nothing to environment.conf and hiera.yaml, they are currently defaults. My init.pp contains:

node 'node1' {
}

node 'node2' {
}

and my java.pp contains:

class { 'java':
  distribution => 'jre',
}

My issue is two fold. One if I place the java.pp in the manifest folder it applies java to both nodes, regardless of if I have called out an include java in either node. If I put the include java on either node, that works correctly and one node will get java and the other will not, but it does not appear to be respecting any of the settings I have in the java.pp. How can I accomplish only installing java to node1 with my custom settings in the java.pp file?


Solution

  • if I place the java.pp in the manifest folder it applies java to both nodes, regardless of if I have called out an include java in either node.

    Yes. The catalog builder processes every manifest file in the environment's manifests directory for every node. Your java.pp file contains a top-scope declaration of class java, so if that file is processed by the catalog builder then it will include class 'java' in the target node's manifest.

    If I put the include java on either node, that works correctly and one node will get java and the other will not, but it does not appear to be respecting any of the settings I have in the java.pp.

    No, it wouldn't. include java (or class { 'java': ... }) declares class java, thereby instructing the catalog builder to include that class in the target node's catalog. The two forms are more or less alternatives, and both will cause the catalog builder to look for the a definition of class java in the environment's module path. Your java.pp hasn't either the right name or the right location to be found in that search, which is good because it does not in fact contain the wanted definition.

    To customize class parameters, you should start right away with external data and automatic data binding. This is not the only way to bind values to class parameters, but it's the mechanism you should prefer, especially for declaring classes across module boundaries.


    Regarding Hiera details, a very basic Hiera config for this purpose might consist of these parts:

    example/hiera.yaml

    # example/hiera.yaml
    ---
    version: 5
    
    defaults:
      datadir: data
      data_hash: yaml_data
    
    hierarchy:
      - name: "Common data"
        path: "common.yaml"
    

    example/data/common.yaml

    ---
    java::distribution: jre
    

    The "example" in those file names would be the main directory of your environment of the same name. Note, by the way, that although you can add a new hierarchy level for every module, that would be unusual. It's more typical to use hierarchies that map to an hierarchical categorization of the machines being configured; naming in the above anticipates such an arrangement, in which as yet there is only one category.

    After having updated the module data, you might find that you need to make the master expire its environment cache. One way to do that would be to restart the service.