The objective here is to create a users cookbook with data bags
Create the data bag
knife data bag create user_config
Create the user json file
data_bags/users/usr_sri.json
"id": "sri", { "comment": "Sriram Rajan", "uid": 2000, "gid": 0, "home":"/home/sri", "shell":"/bin/bash", "pubkey":"<replace with the SSH public key" }
knife data bag from file users_config usr_sri.json
Create a key for the encrypted data bag
openssl rand -base64 512 > data_bags/users/enckey
Create the encrypted data bag
knife data bag create --secret-file data_bags/users/enckey password_config pwdlist
Edit the data bag
knife data bag edit --secret-file data_bags/users/enckey password_config pwdlist
"id": "pwdlist", { "sri": "Replace with SHA password string" }
At this point you should have a data bag with users and encrypted data bag with passwords. Now we move to the cookbook
Create the cookbook
knife cookbook create user_config
Recipe looks like this. We add the user and also ensure the .ssh directory is created and populated with the public keys. The password will be pulled from the encrypted bag.
decrypted = Chef::EncryptedDataBagItem.load("password_config", "pwdlist") search(:user_config, "*:*").each do |user_data| user user_data['id'] do comment user_data['comment'] uid user_data['uid'] gid user_data['gid'] home user_data['home'] shell user_data['shell'] manage_home true password decrypted[user_data['id'] action:create end ssh_dir = user_data['home'] + "/.ssh" directory ssh_dir do owner user_data['uid'] group user_data['gid'] mode "0700" end template "#{ssh_dir}/authorized_keys" do owner user_data['uid'] group user_data['gid'] mode "0600" variables( :ssh_keys => user_data['pubkey'] ) source "authorized_keys.erb" end end
The template file
base_users/templates/default/authorized_keys.erb
<% Array(@ssh_keys).each do |key| %> <%= key %> <% end %>
Finishing up
knife cookbook upload user_config
Ensure the secret key for the encrypted data bag is also sent to the node and stored under /etc/chef/encrypted_data_bag_secret. You can bootstrap this file into the node build. See http://docs.opscode.com/essentials_data_bags_encrypt.html
Then add the recipe to a role or node run list and run the chef-client to test.