Puppet Resources overridden using Hiera

61 views
Skip to first unread message

Danny Roberts

unread,
May 21, 2014, 1:21:17 PM5/21/14
to puppet...@googlegroups.com
I currently have a custom module that applies our companies' standard server config across all servers using Hiera. This includes a class called company::sshkeys that has various 'user' resource types (the standard puppet type) defined for all of our admins, for example:

class company::sshkeys {

  user {  "jane.doe":
                ensure  => present,
                gid     => "company",
                home    => "/home/jane.doe",
                managehome => true,
                shell => "/bin/bash",
                require => Group["company"]
        }

}

This is a slight simplification as the same class also includes our SSH public keys hence the name.

I now find myself in the situation where I need to deny access to certain admins on a single server. We use Hiera in our set-up as much as possible and I would like to use Hiera to in the case of a single server tell Puppet to not create certain user accounts. I have tried many ways to do this but I am unsure on how to call the base resource types even though they are embedded in a custom class or even if such a thing is possible.

Any thoughts on the cleanest way to exclude certain users from getting an account?

Doug Forster

unread,
May 21, 2014, 1:44:00 PM5/21/14
to puppet...@googlegroups.com
Try getting your user list from hiera. Then it will easily be overridden on a server basis.

class company::sshkeys ( users, ) {
 
  users.each |$my_user| {
    user {  $my_user:
      ensure  => present,
      gid     => "company",
      home    => "/home/${my_user}",

--
You received this message because you are subscribed to the Google Groups "Puppet Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to puppet-users...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/puppet-users/5d0c1ae8-4c26-4135-b7b0-1146d97c9e53%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Danny Roberts

unread,
May 21, 2014, 2:58:22 PM5/21/14
to puppet...@googlegroups.com
For some reason my Puppet install doesn't like that:

Error: Could not retrieve catalog from remote server: Error 400 on SERVER: Syntax error at 'users'; expected ')' at /etc/puppet/modules/company/manifests/sshkeys.pp:1 on node puppetmaster
Warning: Not using cache on failed catalog
Error: Could not retrieve catalog; skipping run

Doug Forster

unread,
May 21, 2014, 3:47:21 PM5/21/14
to puppet...@googlegroups.com
My apology the .each functionality is only available if parser=future.
http://docs.puppetlabs.com/puppet/latest/reference/experiments_future.html


jcbollinger

unread,
May 21, 2014, 4:25:00 PM5/21/14
to puppet...@googlegroups.com


On Wednesday, May 21, 2014 1:58:22 PM UTC-5, Danny Roberts wrote:
For some reason my Puppet install doesn't like that:

Error: Could not retrieve catalog from remote server: Error 400 on SERVER: Syntax error at 'users'; expected ')' at /etc/puppet/modules/company/manifests/sshkeys.pp:1 on node puppetmaster
Warning: Not using cache on failed catalog
Error: Could not retrieve catalog; skipping run


As Doug acknowledged, that requires turning on the future parser, which PL does not recommend for production systems.  But no sweat, you can do this with the conventional parser almost as easily.  You need to grease the wheels with a defined type:

define company::user ($ensure = 'present') {
  user { $title:
    ensure  => $ensure,
    gid     => "company",
    home    => "/home/${title}",
    managehome => true,
    shell => "/bin/bash",
    require => Group["company"]
  }
}

Then you can do this:

class company::sshkeys ( users, ) {
  company::user { $users: }
}


That's as far as your example suggested you wanted to go, but do note that it does nothing to remove previously configured users that you no longer want.  If that's a concern to you then you could consider purging unmanaged users via a Resources meta-resource.


John

Danny Roberts

unread,
May 22, 2014, 3:44:06 AM5/22/14
to puppet...@googlegroups.com
That's been a great help.

I have been able to use the config you presented to create user's defined in Hiera. I am just trying to expand upon that.

Currently I do a:

---
users:
  jane.doe


The value 'jane.doe' is obviously passed to the $title variable. Is it possible to pass a second variable into the same loop in order to set something else unique to each user?

Additionally can this be adapted to remove users from certain servers via Hiera at all? You mention 'Resources meta-resource' but I cannot see the connection if any.

jcbollinger

unread,
May 22, 2014, 9:32:25 AM5/22/14
to puppet...@googlegroups.com


On Thursday, May 22, 2014 2:44:06 AM UTC-5, Danny Roberts wrote:
That's been a great help.

I have been able to use the config you presented to create user's defined in Hiera. I am just trying to expand upon that.

Currently I do a:

---
users:
  jane.doe


The value 'jane.doe' is obviously passed to the $title variable. Is it possible to pass a second variable into the same loop in order to set something else unique to each user?



Although Puppet may implement it via a loop, you should think of it more like SIMD parallelism, where the multiple data (MD) part is only the resource title.  It is a shorthand for declaring multiple resources, all with the same parameters, combined with the normal features of any defined type.

Even though each defined type instance gets the same parameter values, they can nevertheless be further customized per-instance by making them draw on data keyed to their titles.  There are many ways to do that, but here's one I tend to like: rather than $company::sshkeys::users being an array of user names, make it a hash with usernames as keys and property hashes as values.  Then modify my approach above like so:

class company::sshkeys ( $users ) {
  # $users is expected to be a hash, with its keys the usernames
  $usernames = keys($users)
  company::user { $usernames: }
}

define company::user ($ensure = 'present') {
  # The values of $company::sshkeys::users are expected
  # to be hashes of (property name, property value) pairs
  # associated with the named user.
  $mydata = $company::sshkeys::users[$title]
  $mygroup = $mydata['group']
  $mykey = $mydata['sshkey']


  user { $title:
    ensure  => $ensure,
    gid     => $mygroup,
    home    => "/home/${title}",
    managehome => true,
    shell => "/bin/bash",
    require => Group["company"]
  }

  #...
}


The keys() function comes from PuppetLabs's 'stdlib' add-in module.

 
Additionally can this be adapted to remove users from certain servers via Hiera at all? You mention 'Resources meta-resource' but I cannot see the connection if any.


There are at least two ways to make that approach remove unwanted users.  One would involve moving the 'ensure' parameter into your per-user data, so that you could specify certain users 'absent'.  That has the drawback that you must enumerate all the users you want to ensure absent.  What I was talking about was making a declaration such as this:

resources { 'user':
  purge => true,
  unless_system_user => true
}

That will purge users that are not otherwise managed by Puppet from the target system, except those that are considered 'system users' as judged by the numeric value of their UIDs.  The docs for the Resources resource type explain in somewhat more detail.  That has the potential drawback that all user accounts you want to keep must be either Puppet-managed or 'system' users.  Also, it probably won't work well on systems configured for LDAP or NIS users, or similar, where users are centrally-managed.


John

Reply all
Reply to author
Forward
0 new messages