[chef] Re: Re: Configure/deploy multiples apps per cookbook, how?


Chronological Thread 
  • From: Andrea Campi < >
  • To:
  • Subject: [chef] Re: Re: Configure/deploy multiples apps per cookbook, how?
  • Date: Thu, 16 Aug 2012 08:46:16 +0200

On Thu, Aug 16, 2012 at 6:12 AM, Marcelo de Moraes Serpa
< >
 wrote:
> Hi guys,
>
> Anyone out there? :) If for some reason it wasn't clear, please let me know.
> I'd really appreciate some insights.

It was pretty clear, it's just a question that doesn't lend itself to
a short, definitive answer :)
So here is mine, and keep in mind it's just my own, and it's pretty 
opinionated.

Think of Chef cookbooks and recipes in terms of code ("infrastructure
as code" is IMHO an even more relevant buzzword that "devops" in this
context ;) ).
If you have several, mostly unrelated applications, then surely it's
ok to have several, mostly unrelated Chef cookbooks. The number of
them shouldn't concern you so much, as long as they are manageable.
Just what "manageable" means in this context varies based on your
company, your understanding of Chef (and Ruby) and so on. You'll have
to find what works for you, best practices notwithstanding.

Your concern with code duplication however is more interesting.
If you think in terms of code, you'll want to factor out common
aspects of the application stacks you manage, and make them into
reusable pieces of Chef code.
Some existing cookbooks provide LWRPs for this; and you can write your own.


For Rails apps, look at the application cookbook and the matching
application_ruby.
Here is an example from a real app I'm deploying:


application "myapp" do
  path           node['myapp']['root']
  owner         "user"
  group         "group"
  repository   
" :myapp.git"
  deploy_key "——BEGIN RSA PRIVATE KEY——\n…\n——END RSA PRIVATE KEY——"
  revision      node.chef_environment == "production" ? "release/0.5"
: "develop"
  migrate      true

  rails do
    gems ["bundler"]
    bundler_deployment true
    precompile_assets true

    database do
      adapter   "postgresql"
      database  "myapp"
      username  "myapp"
      password  "myapp"
    end
    database_master_role  "myapp_database_master"
  end

  passenger_apache2 do
    webapp_template "myapp.conf.erb"
  end
end

This resource uses the deploy resource you've probably read about in
that article you link to (checks out from git if changed, manages
symlinks similar to Capistrano etc).
In addition it will automatically do create database.yml, run a bundle
install, precompile assets for Rails3.
And finally, create your Apache vhost and restart Apache when necessary.

Regardless of the exact details, there is IMHO as little boilerplate
as can be; most of the arguments are really app-specific.
So when I have a new app to deploy, I just create a new cookbook with
something similar in its default recipe.
Similar apps will probably have recipes that are very similar; but the
difference are very important, and being able to see all vital aspects
of that app at a glance trumps DRYness.



That said, there may be cases where you are deploying the same app (or
a very similar one) many times.
For instance I imagine your RefineryCMS instances will be mostly the same.
I also assume you are deploying multiple RefineryCMS instances on the
same server, otherwise it would be trivial ;)

In that case, a common pattern is to make such a deployment data-driven.
You can store information about each separate instance info a data
bag, or in an Array attribute; it's up to you, and different people
will give you different answers.

Assuming you have a "refinerycms_instances" data bag, you would end up
with something like:

search(:refinerycms_instances) do |site|
  if (site["server_roles"] & node.roles).any?
    application "refinerycms: #{site["id"]}" do
      repository   
" :refinerycms.git"
           # the same
for all instances, probably
      path           "/data/refinerycms/#{site["id"]}"         # different
      ..
    end
  end
end

In this case you do have a single cookbook for all your
quasi-identical apps, at the cost of a little bit of extra ceremony.
It's still pretty readable, and it's still pretty easy to see what is
common to all instances and what is per-instance.
Unless you are going to deploy all apps to all nodes, you will need a
little bit of extra ceremony (see the "site["server_roles"] &
node.roles" line); but that's a small price to pay for this kind of
flexibility.


Hope this helps.
  Andrea



Archive powered by MHonArc 2.6.16.

§