Getting Started with Chef Server. Part 2

Hello my dear friends. Today, we will continue talking about Chef Server, and all the example code can be found here: the previous article we’ve learned Chef, Chef Server and its setup process. In this article we’ll figure out how to work with it.

Directory .chef

In the Part 1 article we set up chef server and added one node (server) to it. For an authentication with chef server we use ssh keys; and for knife we have a configuration in knife.rb. All this stuff should be in “.chef” directory. Here’s our modified knife.rb file (fixed paths for keys):When a node runs the chef-client for the first time, it does not yet have an API client identity, and therefore can’t send authenticated requests to the server. This is where the validation client — known as the chef-validator — comes in. When the chef-client runs, it checks if it has a “client_key”; and if the client key does not exist, it tries to borrow the chef-validator identity to register itself with the server (“validation_key”).

Attribute Precedence

Attributes are always applied by the chef-client in the following order:
  1. A default attribute located in an attribute file
  2. A default attribute located in a recipe
  3. A default attribute located in an environment
  4. A default attribute located in role
  5. A force_default attribute located in an attribute file
  6. A force_default attribute located in a recipe
  7. A normal attribute located in an attribute file
  8. A normal attribute located in a recipe
  9. An override attribute located in an attribute file
  10. An override attribute located in a recipe
  11. An override attribute located in a role
  12. An override attribute located in an environment
  13. A force_override attribute located in an attribute file
  14. A force_override attribute located in a recipe
  15. An automatic attribute identified by Ohai at the start of the chef-client run
Attribute precedence in the form of an overview diagram, where the numbers in the diagram match the order of attribute precedence:overview_chef_attributes_precedence.png 2013-09-25 16-47-03 overview_chef_attributes_table

Power of Environments

Environment is a way to map an organisation’s real-life workflow on what can be configured and managed when using server. Every organisation begins with a single environment – a so called _default environment – which cannot be modified (or deleted). Additional environments can be created to reflect each organisation’s patterns and workflow. Creating production, staging, testing, and development environments is a good example. An environment can be also associated with one (or more) cookbook versions.A per-environment run-list is a run-list that is associated with a role and a specific environment. There’s more than one environment that can be specified in a role, but each specific environment may be associated with only one run-list. If a run-list is not specified, the default run-list will be used. For example:where:
  • “webserver” is the name of the role
  • “env_run_lists” is a hash of per-environment run-lists for production, preprod, test, and dev
  • “production” and “preprod” use the default run-list because they do not have a per-environment run-list
  • “run_list” defines the default run-list

Chef Server And SSL Self-Signed Certificate

As you might recall from the previous article, Chef is by default working on https protocol only (security!). This can be a problem however, if you don’t want to buy a valid ssl certificate for your chef server, because each command to chef server by knife will give you error with invalid ssl. The most simple solution – disable https and work only on http. For this lets modify our chef.js on role:I’ve added sections “nginx” which allows us to work with Chef server by http protocol and “bookshelf” which should write url to chef server without https. If we leave https, bookshelf will be available only by https.

Cookbooks, roles and nodes on chef server

If compared with Chef Solo, Chef Server stores all the information on server and uses only this information for “cooking” nodes. Therefore, we should know how to upload our roles, cookbooks and nodes on server. First of all, we should install vender cookbooks locally by Berkshelf:Let’s add python chef cookbook to Berkshelf and run this command again:As you can see, dependencies downloaded automatically. Right now we have these cookbooks only in our local directory “cookbooks”. Let’s upload it to Chef Server. For this task we can use knife:or we can use Berkshelf:If you’re actively developing a cookbook, sometimes you might not want to change version with every little fix. Chef server, however, will not allow uploading same versions of cookbook by default:Apparently, we can force update cookbooks by option ”–force”:All your cookbooks can be viewed in the web interface (if you enable it):chef_cookbooks_listThen, we want to upload or update roles on server. It’s also easy:This is a role in the web interface:chef_role_showAlmost same commands for environment upload or update:or nodes:You can also upload everything using “upload” command:Just don’t forget to do this. It is also a good point to save current nodes, environments and roles in git (hg, svn, etc.) repo, because if you somehow lose chef server, all cookbooks and recipes will be saved.

Cooking of the nodes

Let’s now cook our node “”. We will install on it python. So let’s add to “web.node” run list:And update web.node on chef server:chef_server_nodeBy default, chef client on nodes will not execute your run_list, but you can execute any command on nodes by command “ssh”. For example, run chef client on all nodes:For this command you can use ssh options:The ‘name:*’ is query, ‘sudo chef-client’ which we must execute on nodes found by this query. For example, show uptime only nodes with role web:To upgrade all nodes:Sometimes, however, you may want to update you servers automatically. For example, you’ve just updated new cookbooks, roles and nodes, and all nodes should automatically fetch new cookbooks and execute it, if it’s updated (and for you not critical update speed). We can use special cookbook “chef-client”. It allows using bluepill, daemontools, runit or cron to configure your systems to run Chef Client as a service. Example of attributes for nodes:So, you can add this role for each node. It will check chef server for updates each 1800 sec (30 min).


I haven’t covered many things related to Chef server with this article (i.e.advanced usage, knife-ec2, opsworks – based on chef solo, etc.), but I this should be enough to start working with it.All example code can be found here:’s all folks! Thank you for reading till the end.This is a re-post from my blog.