Hi all,

I've been working on a plugin to manage deployments of clusters on EC2
through Capistrano. I'm looking to see if anyone is interested in
collaborating on it, or using it in alpha form to give me some
feedback. I'm not going to release it yet since it needs more
development and testing, but I would like to get some suggestions on
features to add.

The tool is meant to manage the setup and confiiguration of machines
prior to running a normal cap:deploy of a specific application. It is
not meant to replace that.

Here's an example of a cluster recipe (this is made up, so there may
be some logical errors in the setup, but it should illiustrate the
idea):

-----

cluster = elasticize.creater_cluster("mykey") do
  on_create do |cluster|
    app_group = create_group(cluster, :app) do
      authorize_ingress :proto => :tcp, :ports => 22
      authorize_ingress :proto => [ :tcp, :udp ], :ports => 5036
    end
    webserver_group = create_group(cluster, :webserver_group) do
      authorize_ingress :proto => :tcp, :ports => [ 22, 80 ]
    end

    app_group.authorize_ingress :from => :webserver_group
    webserver_group.authorize_ingress :from => :app_group
  end
end

app = elasticize.create_image :app, 'ami-12345678',
cluster, :app_group
web = elasticize.create_image :web, 'ami-87654321',
cluster, :webserver_group do
  on_create do
    # Get security updates
    run "aptitude update -y"
    run "aptitude upgrade -y"
  end
end

elasticize.create_role :postfix, web do
  on_create do |process|
    modify "/etc/postfix/main.cf" do |r|
      r.sub(/(^myhostname[^=]*=.*$)/, "myhostname =
#{process.instance.dns}")
    end
  end

  on_stop { run "/etc/init.d/postfix stop" }
  on_start do |process|
    run "/etc/init.d/postfix start"
      process.notify! :app, :port => 1234
  end
end

elasticize.create_role :app, rails do
  needs :db, :primary => true
  needs :postfix

  on_receive do |process, source, event, *rest|
    if event == :on_start
      case source.role.name.to_sym
      when :db
        ip = process.instance.private_dns
        port = *rest
      when :postfix
        # TODO: modify the rails configuration to point to the postfix
server
        ip = process.instance.private_dns
        port = *rest
      end
    end
  end
end

# Create an elastic role for the web server, bound to the 'rails' AMI
elasticize.create_role :web, rails do
  needs :app

  on_receive do |process, source, event, *rest|
    if event == :on_start
      case source.role.name.to_sym
      when :app
      end
    end
  end

  on_create do
    # Install needed gems
    install_gem "daemons"
    install_gem "gem_plugin"
    install_gem "mongrel_cluster"
    install_gem "mongrel", :version => '1.0.1'
  end
end

-----

You can then create the cluster with a cap cluster:create. This will
create the keys, security groups, permissions and instances. When a
particular instance is created, its corresponding image's 'on_start'
callback is called. Additionally, the create task will bind all
'elasitc' roles to a particular machine and create the appropriate
capistrano role internally. When the binding occurs, the corresponding
on_start callback are called for the process' corresponding role.
There are additional callbacks when instances are terminated or leave
the cluster.

The 'needs' method indicates that a particular elastic role is
dependent upon another, and that its' processes will accept
notifications (in the on_receive handler) of specific events within
the cluster from prerequisite processes (where a process represents a
binding of a role to an EC2 instance, since a role can have multiple
processes). The notifications are specified via the notify! method in
a process' on_start callback, and allows that process to deliver
dynamic configuration data to its dependent roles' processes.

The 'provides' method specifies the number of processes which will
exist for a given role. Also, 'create_role' can specify capistrano
subroles (limited to a hash of keys to boolean values for now) like
this:

primary = elasticize.create_role :db, some_image, :primary => true do
  # Default is one if unspecified
  provides :exactly => 1
end

secondary = elasticize.create_role, :db, some_image do
  provides :min => 2, :max => 4
end

A planned feature will allow you to add and remove processes
dynamically, bounded by the min / max number specified in the recipe.

cap cluster:add ROLE=db

This is not meant to be a thorough write up, just a taste if what is
available.

If you think you may be able to help, or just have some ideas for what
you'd like to see, please get in touch. In particular, API feedback or
help writing tests would be greatly appreciated.

Joe


--~--~---------~--~----~------------~-------~--~----~
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at http://groups.google.com/group/capistrano
-~----------~----~----~----~------~----~------~--~---

Reply via email to