3

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 "foobar.example.org" {
    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 apt.puppetlabs.com, 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).

1
  • Your question saved me. So. Just thanks :). Cool example
    – AAlvz
    Aug 14, 2014 at 16:22

1 Answer 1

5

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 => { } }

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .