Adoptable Cookbooks List

Supermarket Belongs to the Community

Supermarket belongs to the community. While Chef has the responsibility to keep it running and be stewards of its functionality, what it does and how it works is driven by the community. The chef/supermarket repository will continue to be where development of the Supermarket application takes place. Come be part of shaping the direction of Supermarket by opening issues and pull requests or by joining us on the Chef Mailing List.

rackspace_users

Supported Platforms

Attributes

node['rackspace_users']['data_bag'] : Which data bag contains the item with user records. Defaults to common

node['rackspace_users']['data_bag_item'] : The item that holds the user records. Defaults to users

node['rackspace_users']['node_groups'] : An array of strings representing membership groups declared by the node calling the recipe. These are used to create users and grant sudo to them only on specific nodes. Defaults to [] (empty array).

Usage

The recipe reads the users from an encrypted data bag item. By default, looks for a data bag named common and an item called users. This can be overwritten in the consuming cookbook.
After you define the users in the data bag, place a dependency on the rackspace_users cookbook in your cookbook's metadata.rb:
depends 'rackspace_users'
Then, in your recipe
include_recipe 'rackspace_users'

Provides a method of adding users and grant sudo only on specific nodes via attributes

Overview

The recipe logic is driven by user records in the data bag. Data bag name defaults to common and the item name to users but they can be overwritten.
An example of a users data bag item:
```
{
"id": "users",
"testuser": {
},
"newuser1": {
"sudo": {

The basic attribues of a user are named exactly as the parameters used by the user_account resource and can be added or omitted completely in which case default values are used. In fact users can be added by simply adding records like:
{
"id": "users",
"user1": {},
"user2": {},
"user3": {}
}
Here is an example with some basic attributes:
{
"id": "users",
"newuser": {
"comment": "another new user",
"uid": 2000,
"gid": 2000,
"shell": "/bin/dash",
"home": "/home/custom_home_directory",
"password": "$6$bLZbaeySMzRx7P29$cmmF4SbtnXe2Gc1cBc0fpnBUEPxrr8inn6SNq9xpcT7M/vM0FpZmGF105LWrGCValjJMqEtBALZOYayppwJAj/",
"ssh_keygen": true,
"ssh_keys": [
"key1",
"key2"
],
"groups": [
"newgroup2"
],
}
}
The above example also shows the usage of the groups array which is a list of Linux groups that the user will be granted membership. The group will be created if doesn't exist.

Creating users only on specific servers

User creation on nodes can be controlled by declaring a list of groups on the node consuming the recipe and then subscribing the user to at least one of those groups in the data bag. The user will be created on the node if the user subscribes to at least one of the groups the node declares or if the user doesn't define them at all. Groups declaration on the node can be done in the consuming recipe, for example:

And then on the data bag the user can subscribe to one of the groups like:

{
"id": "users",
"newuser": {
"node_groups": ["admin"]
}
}

The recipe also creates Linux groups named after the node_groups that the user subscribes to and are also found in the node_groups list that the node declares. In the case above, the admin group will be created and the newuser will be granted membership on it. These Linux groups can be used in the future to grant privileges only to members of that groups if desired.

It is worth emphasizing that this membership mechanism is an optional feature: if the node and user don't use it then the user will simply be created on all nodes consuming the recipe.

More complex membership requirements can be handled by approprieatly naming the node_groups items. Here are some scenarios and how they can be implemented using this mechanism:

Other scenarios can be potentially handled by having some logic in the recipe that creates/defines the string to be used in the node['rackspace_users']['node_groups'] attribute. For instance if one wanted to create a user only on nodes with more than 2 CPU cores (because of some strange requirement) then they could potentially do something like this:

Sudo

'Sudo as root' can simply be added by adding an empty sudo section:
{
"id": "users",
"newuser": {
"sudo": {}
}
}
This will add a /etc/sudoers.d/newuser file with privileges allowing the user to execute any command as root. The user will have to enter their password. The recipe uses the sudo resource and some features of that can be overwritten, namely nopasswd, commands and defaults. For example:
{
"id": "users",
"newuser": {
"sudo": {
"nopasswd": true,
"commands": [
"/etc/init.d/httpd restart",
"/sbin/iptables"
],
"defaults": [
"!requiretty",
"env_reset"
]
}
}
}
If there is no sudo section, a sudo entry will not be added for that user. Sudo creation can be controlled even further by again using the node_groups mechanism. If the sudo section has a node_groups sub section then that will be compared against the node_groups the node declares. If no common items are found then a sudo entry will not be added. For example:
{
"id": "users",
"newuser": {
"sudo": {
"node_groups": ["web","admin"]
}
}
}
Also note that if the user doesn't declare node_groups under the sudo section then it is assumed that it has sudo on all nodes.

Using a different data bag

You can point to a different data bag and item by overwriting the corresponding attributes in the consuming cookbook, for example:
```