Can I change node run-list at run time?

Ohai Chef

Can I change node run-list while chef-client is being executed?

Chef-client is being executed with this run-list: ‘recipe[master_cookbook]’, ‘recipe[download]’, ‘recipe[install]’, ‘recipe[configure]’. At the run time of chef-client, my master_cookbook have logic to execute specific cookbook. As a result of one test run, master_cookbook found out that I want to execute only ‘recipe[install]’. How can I forbid the execution of download and configure in that case?


From the description, it sounds like you are treating recipes like scripts. Manipulating the runlist goes against the principles of desired state and doesn’t scale well. A better approach is to make the recipes idempotent. You can do this with guard interpreters, and ‘nothing’ action resources.

Here is an example. A new build is only downloaded if ‘build_number’ changes, or doesn’t exist in the destination. The install and configure are only executed if a new file has been downloaded.

Ideally you would store build_number in a databag, or a node attribute, make it querryable from an api opposed to hard coding in your cookbook.

build_number = 1234

remote_file "#{Chef::Config['file_cache_path']}/build#{build_number}.tgz" do
  source "{build_number}.tgz"
  action :create
  notifies :run, 'execute[install]'
  notifies :run, 'execute[configure]'

directory '/opt/build' do
  action :create

execute 'install' do
  command "tar -xvf #{Chef::Config['file_cache_path']}/build#{build_number}.tgz -C /opt/build"
  action :nothing

execute 'configure' do
  command 'foo'
  action :nothing

If you want to change run_list(cookbooks) at run time, use chef-client -o cookbook_name