I am trying to define virtual user & group data in hiera, and then realize it only on the nodes where it's needed, by defining user lists and group lists on a per-host basis. Note: I am using the accounts
module from puppet forge, and it utilizes the accounts::
name space in hiera. For example, just as a baseline for something that works, if I create this:
# snippet from hiera.yaml
hierarchy:
- name: "Users and Groups"
glob: "UsersAndGroups/*.yaml"
and
# snippet from data/UsersAndGroups/webadmins.yaml
accounts::user_list:
alice:
uid: '999'
gid: '999'
comment: 'Alice User'
shell: '/bin/bash'
bob:
uid: '998'
gid: '998'
comment: 'Bob User'
shell: '/bin/bash'
It works, but the problem is, alice
and bob
get created on all machines. I only want them to be created on some. I would like to instead, define this data in hiera as virtual and then use a different data structure to specify which resources should be realized on each machine, for example:
# snippet from data/UsersAndGroups/webadmins.yaml
accounts::user_list:
@alice:
uid: '999'
gid: '999'
comment: 'Alice User'
shell: '/bin/bash'
@bob:
uid: '998'
gid: '998'
comment: 'Bob User'
shell: '/bin/bash'
and then create another data structure (and corresponding puppet class, not shown), like so:
# snippet from data/users_by_host/hosts.yaml
realize_accounts::by_host:
host1.example.dom:
- alice
- bob
host2.example.dom:
- bob
host3.example.dom:
- alice
I've tried every variation I can think of to make this work, but have failed so far. The first problem is the virtual resource declaration. It doesn't like me using the @
symbol. I receive the error message: found character '@' that cannot start any token.
Can anyone suggest how to abstract the user definitions from the selection of which users should be created on which machines?
I am trying to define virtual user & group data in hiera, and then realize it only on the nodes where it's needed, by defining user lists and group lists on a per-host basis.
Ok, that's not unreasonable.
Note: I am using the
accounts
module from puppet forge, and it utilizes theaccounts::
name space in hiera.
You can use the puppetlabs/accounts module, but you cannot use its accounts
class to manage users or groups if you want to stick to your plan, because it does not provide for declaring those virtually. That is a function of the Puppet code of the declarations, not (directly) of any data the class consumes.
You can still use the Accounts::User
defined type, the module's various custom data types, and its custom functions. These perhaps provide enough of a value-add relative to Puppet's core User
resource type to make the module worth it. You're probably looking at the core Group
resource type in any case. You would need to declare Accounts::User
(or User
) and Group
resources virtually, and then realize the wanted ones based on your per-host lists.
But there are other alternatives. You clarified in comments that your objective is to centralize master lists of user and group properties, from which you can select subsets on a per-machine basis. You can do all of that directly in Hiera with the help of Hiera's alias()
interpolation function.
You would do this with a two- (at least) level hierarchy. The user and group details would go into an hierarchy level shared by all hosts, and perhaps accounts::user_defaults
and accounts::group_defaults
would go there too, if you use them. The accounts::user_list
and accounts::group_list
would go in a per-host or an otherwise more specific hierarchy level, interpolating elements from the central list. Example:
common.yaml
user:
alice:
uid: '999'
gid: '999'
comment: 'Alice User'
shell: '/bin/bash'
bob:
uid: '998'
gid: '998'
comment: 'Bob User'
shell: '/bin/bash'
host1.yaml
accounts::user_list:
alice: "%{alias('user.alice')}"
bob: "%{alias('user.bob')}"
host2.yaml
accounts::user_list:
bob: "%{alias('user.bob')}"
host3.yaml
accounts::user_list:
alice: "%{alias('user.alice')}"