Question

We use Chef (Chef-Solo) for creating our hosted site nodes, and for that it is wonderful.

We keep track of our nodes as JSON files using knife solo. Our node configurations (json files) themselves are checked into a git repo. We have a one to one relationship between our node setup files and servers (nodes) themselves.

Some nodes host multiple sites for a client, and it would be nice to have a lightweight solution for running the deployment portion of the chef process for just one of the sites, rather than run the whole Chef node setup process.

I realize this may be using chef in a way it wasn't intended to be used. I get "pull" methodology of Chef, and it's idempotence, how it is for configuration management and how this type of thing falls outside the scope of what one would normally do. Put simply... I want to leverage the Chef deploy resource for deploying sites, but without deploying all sites on a particular server.

Also, I am familiar with Capistrano and how it more or less accomplishes what I want to do... I simply don't want to introduce another framework to our DevOps workflow if I can help it. See as though Chef seems to deploy in a very similar way to Capistrano, I am hoping there is a way to leverage Chef like this.

Thanks

Was it helpful?

Solution 3

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.

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.

OTHER TIPS

The only idea I have is chef-apply

you can use multiply chef cookbooks - one cookbook for one client site. And deploy site in this cookbooks.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top