automationyamlpuppetpuppet-enterprisehiera

Assess hashes value in puppet manifest from hiera


I'm having difficulty in calling the hashes value in my puppet manifest, my code as below,

hiera .yaml file:

---
users:
  app1:
    ensure: 'present'
    home: '/home/app1'
    password: '!!'
    password_max_age: '99999'
    password_min_age: '0'
  app2:
    ensure: 'present'
    home: '/home/app2'
    password: '!!'
    password_max_age: '99999'
    password_min_age: '0'

My puppet manifest:

class profile::sec::sec_model {
hiera_hash('users').each |String $user, Hash $user_hash| {
    $user_hash.each |String $attr, String $value| {
        user { "$user":
            "${attr}" => "${value}"
       }
    }
}
}

My goal is to create user app1 and app2, if using normal manifest as below, i able to create it, as example below,

user { 'app1':
        ensure            => "present",
        home              => "/home/app1",
        password          => '!!',
        password_max_age  => '99999',
        password_min_age  => '0',
        shell             => '/bin/bash',
    }
}

However, when using hiera, i received an error as below from the test puppet client server,

Error: Could not retrieve catalog from remote server: Error 500 on SERVER: Server Error: Syntax error at '' (file: /etc/puppetlabs/code/environments/xxxxx/site/profile/manifests/xxx/sec_model.pp, line: 11, column: 13) on node xxxx.xxx.com

When I look into my manifest everything is good, but cannot identify which side of code for calling the hash value is wrong.


Solution

  • Yes, that's not valid syntax.

    So, you should refactor your YAML as:

    ---
    profile::sec::sec_model::users:
      app1:
        ensure: present
        home: /home/app1
        password: '!!'
        password_max_age: 99999
        password_min_age: 0
      app2:
        ensure: present
        home: /home/app2
        password: '!!'
        password_max_age: 99999
        password_min_age: 0
    

    And then for your manifest, use either:

    class profile::sec::sec_model(Hash[String,Hash] $users) {
      $users.each |$user,$user_hash| {
        user { $user: * => $user_hash }
      }
    }
    

    Or, simply:

    class profile::sec::sec_model(Hash[String,Hash] $users) {
      create_resources(user, $users)
    }
    

    Noting that not everyone in the Puppet community likes using create_resources.

    Further explanation: