Puppet [SOLVED]: Puppet – set defaults in manifest if not present in hiera when iterating over hash

Puppet [SOLVED]: Puppet – set defaults in manifest if not present in hiera when iterating over hash

Home Forums Automation Tools Puppet Puppet [SOLVED]: Puppet – set defaults in manifest if not present in hiera when iterating over hash

Viewing 2 posts - 1 through 2 (of 2 total)
  • Author
    Posts
  • #244922

    Cloudy Point
    Keymaster

    QuestionQuestion

    I am iterating over many entries in a hiera hash, and wish to remove identical duplicate lines from hiera by setting defaults in the manifest (such as ensure, groups, managehome etc), and have the defaults overridden IF the duplicate key/value pair exists in hiera.

    To date, everything I have tried fails to get the default values. I get the idea that I need to declare a resource, but am uncertain.

    I have tried setting “default_values_hash” in the lookup and other methods, but nothing appears to pass defaults into the iteration and –debug output

    This is a (pseudo) example of my manifest and hiera data. Any guidance is sincerely appreciated. Thank you.

    class test (
      Hash $testhash = lookup('test::hash', "merge" => 'hash'}),
    ){
    
      $testhash.each |$key, $value| {
        user { $key :
          ensure     => $value['ensure'],
          name       => $value['name'],
          password   => $value['password'],
          groups     => $value['groups'],
          managehome => $value['managehome'],
        }
      }
    }
    include class test
    

    in Hiera:

    test::hash:
    
    'fred':
      name:         fred
      password:     somepassword
      groups:       wheel
      managehome:   true
    
    'mary':
      name:         mary
      password:     otherpassword
    
    'john':
      name:         john
      password:     anotherpassword
    
    'harry':
    

    Setting resource defaults in the manifest (with capitalized User) does not pass into the iteration, though it does if I keep all data in the manifest (too much data to do that).

    #244923

    Cloudy Point
    Keymaster

    Accepted AnswerAnswer

    The lookup function gives you the ability to establish a default value for the hash itself, but not really for the keys and values inside the hash. Additionally, using the lookup function as a class parameter value in Puppet will be superseded by automatic parameter bindings. In other words, your lookup function in this context does nothing because Puppet is preferring automatic parameter bindings over it, and you are using those (this is definitely true for lookup in conjunction with Hiera 5, which it appears you are using). I personally find this behavior annoying, but it is what it is. Edit: Never mind on that specific reasoning; the parameter is called $testhash and not $hash. If that parameter is coming from module data though, then the lookup will still be ignored since Puppet only allows automatic parameter binding for module data.

    I am surprised that the resource defaults are not working here for you. I have to believe that this is either unintended, or something was implemented wrong regarding them when you went that route.

    Regardless, here is a guaranteed method for you. First, we implement per-expression default attributes: https://puppet.com/docs/puppet/5.3/lang_resources_advanced.html#per-expression-default-attributes

    class test (
      Hash $testhash = lookup('test::hash', "merge" => 'hash'}),
    ){
    
      $testhash.each |String $key, Hash $value| {
        user { 
          default:
            ensure     => present,
            name       => 'username',
            password   => 'userpassword',
            groups     => ['usergroups'],
            managehome => false,
          ;
          $key:
            ensure     => $value['ensure'],
            name       => $value['name'],
            password   => $value['password'],
            groups     => $value['groups'],
            managehome => $value['managehome'],
          ;
        }
      }
    }
    

    One problem still remains here though, which is that you are establishing values for the attributes in the second block for all iterations. If those key-value pairs are undefined, Puppet will error instead of defaulting to another value. We need to instruct Puppet to only establish values for attributes if you have defined a value for them in the first place. Thankfully, we can do this with the * attribute: https://puppet.com/docs/puppet/5.3/lang_resources_advanced.html#setting-attributes-from-a-hash

    class test (
      Hash $testhash = lookup('test::hash', "merge" => 'hash'}),
    ){
    
      $testhash.each |String $key, Hash $value| {
        user { 
          default:
            ensure     => present,
            name       => 'username',
            password   => 'userpassword',
            groups     => ['usergroups'],
            managehome => false,
          ;
          $key:
            * => $value,
          ;
        }
      }
    }
    

    One recommendation here would be to make your lambda iterator variables $key, $value a bit more transparently named. Another note is the caveat that for the * attribute to work, your hash keys must match Puppet attribute names.

    Updated question: In the situation where the hash has a key with a nil value, you can set an empty hash as the default value for the key’s value in the lambda iterator parameters. The empty hash will replace the undef (Puppet nil) for the $value during that iteration. This will ensure that no attributes and values are included in the * operator and that all the defaults will prevail.

    class test (
      Hash $testhash = lookup('test::hash', "merge" => 'hash'}),
    ){
    
      $testhash.each |String $key, Hash $value = {}| {
        user { 
          default:
            ensure     => present,
            name       => 'username',
            password   => 'userpassword',
            groups     => ['usergroups'],
            managehome => false,
          ;
          $key:
            * => $value,
          ;
        }
      }
    }
    

    Source: https://stackoverflow.com/questions/47922617/puppet-set-defaults-in-manifest-if-not-present-in-hiera-when-iterating-over-ha
    Author: Matt Schuchard
    Creative Commons License
    This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.

Viewing 2 posts - 1 through 2 (of 2 total)

You must be logged in to reply to this topic.