chef-infrachef-soloknifeknife-solo

Site Deployment with Chef but without full Node setup


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


Solution

  • So after extensive R&D I've determined my options chose one. Here are the options and ultimately the one I chose.

    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.