Automate All the Things!

Doug Ireton's blog about Chef, Git, Ruby, Vim, and Infrastructure Automation

Knife Tricks

| Comments

Ohai Chefs!

At work, we have yet to use search extensively in our Chef Recipes, but we do a fair number of ad hoc knife searches. The following are some knife tricks and tips we’ve picked up over the last few months. Most of the credit for these goes to my esteemed co-worker, the Impossibly Hip™ Jon DeCamp.

Find all nodes in an environment

1
$ knife search node chef_environment:<environment name>

Find all nodes which contain a role

1
2
3
$ knife search node role(s):<role name>

$ knife search node "role:web_server" -a hostname

Use ‘roles’ plural when looking in the expanded run list.

Find all nodes which contain a recipe

1
2
3
4
5
# looks for statsd_handler(::default)
$ knife search node "recipes:statsd_handler"

# note the use of \:\: to escape the double-colon
$ knife search node "recipes:windows\:\:reboot_handler"

Note the use of recipes plural to search the expanded run list.

Find all non-64 bit nodes

1
$ knife search node "(NOT kernel_machine:x86_64)"

Return selected attributes from knife search

1
$ knife search node "name:*" -a chef_packages.chef.version

This returns the chef_packages.chef.version attribute from all nodes in the Chef Org.

Add a role to all nodes in an Environment

1
2
3
4
# First, run it like this to run without saving the results back to the Chef Server
$ knife exec -E 'nodes.transform("chef_environment:dev") {|n| puts n.run_list << "role[hosts_file]" }'

$ knife exec -E 'nodes.transform("chef_environment:dev") {|n| puts n.run_list << "role[hosts_file]"; n.save }'

To be on the safe side, run the command above without the n.save so results aren’t saved back to the Chef server. When you are sure about the command run it with n.save to save the results back to the Chef server.

Add a role to all nodes in an Environment which don’t contain the given Role

1
$ knife exec -E 'nodes.find("chef_environment:dev") {|n| puts n.run_list << "role[base]" unless n.run_list.include?("role[base]"); n.save }'

Remove a recipe from all nodes in an Environment

1
$ knife exec -E 'nodes.transform("chef_environment:dev") {|n| puts n.run_list.remove("recipe[chef-client::upgrade]"); n.save }'

Remove all nodes from a given role

1
$ knife exec -E 'nodes.find("role:web_server") {|n| n.run_list.remove("role[web_server]"); n.save}'

Set a node’s run_list back to a single item

1
$ knife exec -E 'nodes.transform("name:webserver01.example.com") {|n| n.run_list(["role[base]"])}'

Conclusion

So that’s it for this week. I hope you picked up some valuable knife tricks. The knife search command is versatile and combining knife exec with search allows you to do some amazing things with your infrstructure. Share some of your own knife tricks in the comments or over on Twitter.

Comments