I am seeing the following error when my Puppet agent is attempting to retrieve the configuration from the Puppet Server (v8), all running on Redhat OS:
Error: Could not retrieve catalog from remote server: Error 500 on SERVER: Server Error: Evaluation Error: Unknown variable: 'ssh_user'
The error refers to a custom resource type defined in a module called "Users".
class users::virtual {
define ssh_user( $user=$name, $uid, $password, $key, $home_dir = 'home' ) {
user { $user:
ensure => present,
managehome => true,
uid => $uid,
password => $password,
home => "/${home_dir}/${user}"
}
ssh_authorized_key { "${user}_key":
key => $key,
type => "ssh-rsa",
user => $user,
}
}
define ssh_home ($home_dir = 'home') {
file { "/${home_base_dir}/${name}/.ssh":
ensure => directory,
owner => $name,
group => $name,
mode => 0700,
} ->
file { "/${home_dir}/${name}/.ssh/id_rsa":
source => "puppet:///modules/users/${name}/ssh/id_rsa",
owner => $name,
group => $name,
mode => 0600,
} ->
file { "/${home_dir}/${name}/.ssh/id_rsa.pub":
source => "puppet:///modules/users/${name}/ssh/id_rsa.pub",
owner => $name,
group => $name,
mode => 0644,
}
}
ssh_user { "myuser":
uid => 1010,
password => 'hidden',
key => "hidden",
}
}
Any ideas why this is happening? I removed @ssh_user and tried $ssh_user but see the same error.
When you define a class or resource type inside the definition of a different one, it goes into the namespace defined by the container. So, with ...
class users::virtual { define ssh_user( $user=$name, $uid, $password, $key, $home_dir = 'home' ) { user { $user: ensure => present, managehome => true, uid => $uid, password => $password, home => "/${home_dir}/${user}" } ssh_authorized_key { "${user}_key": key => $key, type => "ssh-rsa", user => $user, } }
... the (fully-qualified) name of the defined type is users::virtual::ssh_user
.
In Puppet 3 and earlier, Puppet would attempt to resolve class and defined type names such as ssh_user
relative to the innermost local namespace first, working its way outward until it found a namespace wherein the name was defined, or else did not find it even as a top-scope name. That behavior was dropped in Puppet 4. Since then, you always need to refer to classes and defined types by their fully-qualified names. This is one of the lesser of a number of reasons why you should not nest class and defined type definitions.
The best solution, then, would be to lift the ssh_user type to its own file, presumably modules/users/manifests/ssh_user.pp
. In that case, the name by which you reference it would be users::ssh_user
:
users::ssh_user { "myuser":
uid => 1010,
password => 'hidden',
key => "hidden",
}
On the other hand, if you stick with the nested definition then you'll still need to refer to the type via its full name, but that name will be users::virtual::ssh_user
, as already described:
users::virtual::ssh_user { "myuser":
uid => 1010,
password => 'hidden',
key => "hidden",
}
If you want keep the same fuilly-qualified name when you lift the type to its own file, then you can instead put it in modules/users/manifests/virtual/ssh_user.pp
.
Wherever you put the type, if you lift it into its own file then you should define it with its fully-qualified name. For example,
modules/users/manifests/ssh_user.pp
define users::ssh_user( $user=$name, $uid, $password, $key, $home_dir = 'home' ) {
# ...
}