linuxpuppetpuppet-enterprise

Having some trouble using module hiera in puppet


I am having some trouble using module hiera data.

module: /etc/puppetlabs/code/environments/production/modules/usehiera

tree structure:

usehiera
usehiera/hiera.yaml
usehiera/data
usehiera/data/common.yaml
usehiera/manifests
usehiera/manifests/init.pp

hiera.yaml:

---
version: 5
defaults:  
  datadir: data
  data_hash: yaml_data
hierarchy:
  - name: 'common'
  - path: 'common.yaml'

data/common.yaml:

---
usehiera::apples: 'this is some data'

manifests/init.pp:

class usehiera{
    file{'/tmp/hiera_lookup.txt':
        ensure => present,
        #content => hiera('oranges') #this works with global hiera
        content => $apples
    }
}

As you can see I seem to have the global hiera working with "hiera('oranges')" when I run this module on my node. When I try to use the module hiera data the puppet run finishes successfully but hiera_lookup.txt is just empty.

Steps I have taken to troubleshoot:

  1. restart puppetserver after hiera changes
  2. try using $usehira::apples
  3. try using hiera('apples')
  4. moving my hiera.yaml inside data/
  5. using lookup with --explain doesnt really give me anything useful, just says lookup() not found

Can anyone help me out? I have been stuck with this for a decent amount of time and not sure what the issue could be.


Solution

  • As @MattSchuchard pointed out in comments, your hiera.yaml is inappropriately formed. The documentation contains examples.

    But a bigger issue seems to be incorrect expectations. Evidently, you assume that ordinary class variable $usehiera::apples will automatically take the value associated with the corresponding key in the module-level hiera data, but that simply is not the case. Hiera data -- whether global, environment-level, or module-level -- is automatically bound to class parameters, but not to other class variables.

    You can set ordinary class variables from hiera data via explicit lookup:

    # the hiera() function is deprecated; use lookup():
    $apples = lookup('usehiera::apples')
    

    Alternatively, you can make $apples a class parameter:

    class usehiera(String $apples) {
      file{'/tmp/hiera_lookup.txt':
        ensure  => 'present',
        content => $apples,
      }
    }
    

    Note well that if you make it a parameter then its value can also be customized via a resource-like class declaration, which takes precedence over your Hiera data.

    Note also that the difference between global, per-environment, and module-specific Hiera data is just scope and precedence, not functionality.