2

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.

MrAZ
  • 394
  • 3
  • 13

1 Answers1

3

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:

  • This question is quite similar to this earlier question. See there for further information on the "whys" and for further references.

  • Note also that I removed superfluous punctuation in the YAML. I personally consider it a best practice to include only punctuation in YAML files that is actually required, because it is cleaner, and it also forces you to learn when and why punctuation in YAML is required.

Alex Harvey
  • 14,494
  • 5
  • 61
  • 97
  • 2
    For the record, I much prefer the iteration / splat approach over `create_resources()`, but both work, of course. – John Bollinger Mar 14 '19 at 12:04
  • @JohnBollinger Are you referring to this: https://puppet.com/docs/puppet/5.5/lang_resources_advanced.html#implementing-the-createresources-function? – Matthew Schuchard Mar 14 '19 at 12:22
  • The one and only @MattSchuchard. I personally prefer create_resources and my observation has been most non-Puppet people find it clearer. But definitely Puppet people often don’t like it! – Alex Harvey Mar 14 '19 at 12:25
  • 1
    If I had to guess the origin of the distaste, it would be because `create_resources` and inlined defined resource types was the only way to iterate prior to 3.7, and everyone has bad memories of that which are then associated mentally with `create_resources`. Additionally making a function call is not as robust as a lambda, but then I guess why kill an ant with a rocket launcher (in terms of a tool being potentially overkill for a task). – Matthew Schuchard Mar 14 '19 at 12:27
  • @AlexHarvey Thanks Alex, this indeed the answer for my question. However, since my syntax are wrong under my .yaml, but im not understand why it got wrong there, is it to include our class under that .yaml as you wrote here is a must? – MrAZ Mar 14 '19 at 12:39
  • I prefer the explicit iteration and splat-assignment in large part because I find that substantially clearer. Although `create_resources` has the benefit of a descriptive name, its behavior is a bit magic. Also, the splat-assignment version is more flexible (not that it matters in the OP's case), so if I'm going to standardize on one -- and I do prefer to do so -- then the splat version is the one I choose, hands down. – John Bollinger Mar 14 '19 at 12:54
  • If you saw those splats repeated several times in a row in a code base, would you consider writing a function to remove the duplication if in another language like c++? – Alex Harvey Mar 14 '19 at 13:16
  • 1
    @MrAZ, I have created a [gist](https://gist.github.com/alexharv074/8d258549873c91795d5622b82986c772) that explains the syntax problems. – Alex Harvey Mar 14 '19 at 13:20