I have read the Chef docs and understand what cookbooks, recipes, and run_lists are, but still find it hard to decide how to organize a project into cookbook(s), recipe(s), and run_list
s.
What are the conceptual differences between these and in what cases would I ever use something other than 1 cookbook with 1 recipe? (Most the examples/tutorials I have found online only have 1 cookbook with 1 recipe)
Example
I am trying to make a Chef project to get a webapp up and running. Specifically, I want to:
- install JDK 1.8, Tomcat 7, and Postgres 9.3
- start up Postgres with a specific data directory
- configure Postgres (create a database, create a superuser, etc...)
- put a
context.xml
file into Tomcat - start up Tomcat
Should these all go into one cookbook?
Should each of these steps correspond to a separate recipe?
If they all go into 1 recipe, then why are run_list
s useful?
Disclaimer: I am mostly looking into using Chef with knife-solo
, so my confusion might be due to the documentation describing a typical deployment (eg. master with many nodes) when all I care about is running my cookbooks on a specific machine.
Cookbooks and recipes are ways for you to separate concerns and organize code. Breaking up your apps components into individual recipes or cookbooks will make it more readable, testable and maintainable.
Code re-use is another reason. Say your organization wants to build one tomcat cookbook and share it across teams. Then other teams could include that in their runlist to re-use code. It would be more difficult to share one recipe in a cookbook with many other recipes not related to tomcat.
As you start to grow your infrastructure you may also want to move tomcat and postgres on different servers. Having them separated already will make that easier.
Your use case with chef-solo and one server you can Keep it simple and put it in one cookbook.
Yes. Take a look at the example below. These can easily be moved to separate cookbooks if they start to feel too complicated.
A
run_list
could have yourutilities
,app
, anddatabase
cookbooks. This way you can share yourutilities
ordatabase
cookbooks with other servers that may not be related to your app.Here is an example very similar to your use-case where everything is in one cookbook with individual recipes for each part of the stack. These could easily be broken out into cookbooks. https://github.com/erichelgeson/grails-app-server/tree/master/chef-repo/cookbooks/grailsapp/recipes