Linux – puppet loops to create users with values in a raw file

linuxpuppetuser-management

I would like to use puppet to create mailboxes. Basically, I only need a directory to be created when a new user arrives. However, the users list is quite huge and creating a file stanza per user is out of question. I have found a way to pass an array with this stanza:

file { [ "user1", "user2", ... ]:
    ensure => directory,
    owner  => $user,
    group  => 'mail',
    mode   => 0660,
}

There are 2 problems with this: First, there is no way to retrieve the users list from an external resource (which could be a CSV file, for instance). And secondly, I can't see how it is possible to instantiate the owner value.

I have thought to define function, but the same problems remains. Has someone found a solution to solve this problem?

Best Answer

A defined type should work pretty well for the problem of owner.

define usermailbox {
  # creates dir /path/to/username:
  file { "/path/to/$title":
    ensure => directory,
    owner  => $title,
    group  => 'mail',
    mode   => 0660,
  }
}

To populate from an external source, Hiera is a good option - it's integrated in Puppet after 3.0, but you'll need to install it separately on your master system if you're still on 2.7. If you're going to use it, you might also consider moving over to it as a more flexible means of doing your node definitions.

Where you put the users list depends on whether this needs to apply to just one system, or to multiple.. but for now, let's say we want it specific to this system.

So in your /etc/puppet/hiera.yaml (the config for how Hiera looks for data), you'll have something like this:

:backends:
  - yaml

:hierarchy:
  - %{::clientcert}
  - common

:yaml:
   :datadir: '/etc/puppet/hieradata'

For node.example.com, it'll look for a file /etc/puppet/hieradata/node.example.com.yaml (or common.yaml as lower priority, so you can use it instead if you want this list available to multiple servers' catalogs). Create that file, and we'll give it the user list in YAML format:

mailbox_users:
  - user1
  - user2
  - user3

Then, we can use a hiera call to grab that list, pull it in as a variable, and use it to set up the define from above once for each user in the list.

usermailbox { hiera(mailbox_users): }