How would you configure a VM so that it will automatically register with a chef server?

I know that I could use knife bootstrap, however that is very tedious if you are starting dozens of servers at once.

The Chef documentation says to use chef-client -j /etc/chef/file.json and bake the that into the image along with your client.rb and validation.pem files. However that still requires ssh-ing into the machine to run the chef-client command.

Is there not a more automated way to do this?
How do other people provision thousands of machines at once?


I contacted Chef support, they said you can start chef on boot in the following ways.

  1. Add /usr/bin/chef-client to the /etc/rc.local file and ensure you have a client.rb and validatation.pem files in /etc/chef

  2. Use the chef-client cookbook to manage chef and control the init script.

They also said that the chef-client doesn't run as a daemon. Instead it only runs when it needs to do a convergence. (Which seems contradictory to the documentation.)

These solutions introduce new problems though. 1. You will have duplicate chef-client processes running if you add it to the rc.local file 2. You need to run chef in order to manage chef with the chef cookbook. How do you then clean up and unregister the node so that you can take a snapshot?

  • Add chef-client to the post-processing section of your provisioning system. For example, on AWS you could add it to the "run-once" section of the cloud-init configuration. For RHEL you could add it to the %post section of the kickstart file. Jan 27 '15 at 1:18

You have many options.

  1. Use cloud-init to run the chef-client command after the node comes up.
  2. Include a 'service' that runs at startup to run chef-client
  3. script the creation of your nodes using knife ec2 server create or similar commands for other clouds. This will create and bootstrap the node in one command. Wrapped in a script, you could do any number of servers this way.

No matter what approach you take, you need to realize the load that will come in if you don't stagger the server creation. Thousands of machines in a few minutes will require an amazing chef-server, or perhaps a cluster of chef servers.


What you basically need is:

  • chef-server url
  • chef-server certificate
  • validation.pem
  • chef-client

existing on the machine you want to bootstrap.

In your machine bootstrap process place the content of the valiadtion.pem e.g. /etc/chef/validation.pem. Get the chef-server certificate and place it under /etc/chef/trusted_certs/chef-server.pem

Create a /etc/chef/client.rb with the content like

log_level        :info
log_location     STDOUT
chef_server_url  "https://yourchefserver.example.com"
validation_client_name "chef-validator"
file_backup_path   "/var/lib/chef"
file_cache_path    "/var/cache/chef"
pid_file           "/var/run/chef/client.pid"

If you run chef-client right now, you're ending up with the node in the chef-server.

If you want to set a base cookbook as a runlist, you can create something like /tmp/base-run_list.json

"run_list": ["recipe[my_base_cookbook]"]

and apply chef-client -j /tmp/base-run_list.json

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.