Server Fault is a question and answer site for system and network administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I'm new to Puppet and to start using it I want to learn how to manage system users.

I have several users, which share common properties, so I thought I should factor things out.

After some struggle, here's what I came with:

define staff::ssh_key($user) {
    ssh_authorized_key { $name[name]:
        ensure  => present,
        key     => $name[key],
        type    => "ssh-rsa",
        user    => $user,
        require => File["/home/${user}/.ssh"],

define staff($fullname, $ssh_keys, $shell = "/bin/bash") {
    user { $name:
        ensure     => present,
        comment    => "${fullname},,,",
        home       => "/home/${name}",
        managehome => true,
        groups     => ["users", "adm", "sudo"],
        shell      => $shell,

    file { "/home/${name}/.ssh":
        ensure  => directory,
        mode    => 0700,
        owner   => $name,
        require => User[$name],

    staff::ssh_key { $ssh_keys:
        user => $name,

Then I'm declaring users like this:

staff { "drdaeman":
    fullname => "Aleksey Zhukov",
    shell    => "/bin/zsh",
    ssh_keys => [
            name => "desktop",
            key  => "AAAA....6s=",
            name => "notebook",
            key  => "AAAA....Q==",

For a time being, I've just saved both of those parts are saved into a single file, called staff.pp. For remote configuration, I've put site.pp with the following contents:

node "" {
    import "staff.pp"

While everything seem to work fine locally, by calling puppet apply staff.pp, it fails when used remotely. Running puppet agent --test yields me an error:

err: Could not retrieve catalog from remote server: Could not intern from pson: Could not convert from pson: Could not find relationship source "Staff::Ssh_key[namenotebookkeyAAAA...Q==]"
err: Could not retrieve catalog; skipping run

(I'm using Puppet 2.7.14 on Ubuntu, from, if this matters.)

So, it seems, Puppet does not like hashes as resource names, at least not when data's passed over the network. Is there any way I could work around this, not resorting to copy-pasting all required ssh_authorized_key resources by hand? (That would be too verbose to my tastes)

Note, in this exact case I can work around by using simple file "/home/${name}/.ssh/authorized_keys": ... } instead of ssh_authorized_key, or using concat::fragment, however that wouldn't work with other similar cases, where some resource has multiple dependent resources, which do not easily reduce into a single file. Rather, I'm looking for some relatively generic way to possibly solve this and similar situations (if there's any).

share|improve this question
Your question saved me. So. Just thanks :). Cool example – AAlvz Aug 14 '14 at 16:22
up vote 5 down vote accepted

You will need to use create_resource instead of declaring:

staff::ssh_key { $ssh_keys:
    user => $name,

To retain the convenience of user => $name:

Staff::Ssh_key {
     user => $name,    

create_resources('staff::ssh_key', $ssh_keys)

Also change ssh_keys to a hash instead of an array in staff { ... ssh_keys => { } }

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.