So after extensive R&D I've determined my options chose one. Here are the options and ultimately the one I chose.
- chef-apply
- This is a handy utility introduced in chef v11 that allows you to quickly run a recipe. Used mostly for testing.
- Where this falls short, is that to really make a recipe reusable you need to have arguments of some kind or another. This utility didn't seem to support that.
- As I am using knife-solo I have a json file for each "node" managed locally (and in a git repo). For those who are not familiar.. knife-solo uses a json file that matches the name of the host (node) you are connecting to and setting up. I could manage some aliases for my host names that instead select a json file that only deploys the site and nothing additional.
- This requires setting up a recipe used only for deploying the site. Depending on how you have set up your cookbooks and recipes, you may already have the site deployment logic isolated to it's own recipe. If not, you can refactor to do so.
- This would require using the ssh config file extensively. And really isn't very flexible or intuitive. Especially a concern if you anticipate that you may not be the only one using this setup.
- This one is too complicated.
- Stepping outside the realm of the knife-solo, one could run chef-solo on the server directly. This still requires a JSON file to specify the arguments / parameters, and which recipes to run.
- Running
chef-solo -c solo.rb -p deploy.json
on the server is a quick way to run just a subset of the chef server setup process defined in the deploy.json file.
- Running
Putting it all together
The biggest hangup with using the vanilla chef-solo executable is that the parameters must be specified via JSON file (there is discussion on how to specify the JSON inline on the CLI, but doesn't seem to work, at least reliably).
To put it simply there should be a standard server setup JSON file (managed by knife-solo if you want) that contains all the server setup. Then there is a small json file per site on the host that only deploys that one site.
What I did was using the primary chef server setup configuration to create the json files needed for each site. My primary chef process already knows about each one of the sites on the server as it needs to both deploy the site code, set up the database and configure apache, etc. So in addition to all this it creates a json file that indicates a run list and a few other attributes indicating which site to deploy.
I use an .erb file for creating the site deployment json file. For example:
{
"custom_cookbook": {
"deployroot": "<%= @deployroot %>",
<% if @git_revision -%>
"git_revision": "<%= @git_revision %>",
<% end -%>
<% if @settings_file -%>
"settings-file": "<%= @settings_file %>",
<% end -%>
"git_repository_url": "<%= @git_repository_url %>"
},
"run_list": [
"recipe[custom_cookbook::deploy]"
]
}
Once these json files are in place deploying a site with chef is simply running the chef-solo command specified above with the -j parameter specifying the custom site specific json file created by the master/primary chef process.
We initiate deployments via Jenkins (more info on how I use jenkins), though this can be done using anything with SSH access to the site.
Hope this helps.