Pushing to multiple EC2 instances on a load balancer Pushing to multiple EC2 instances on a load balancer php php

Pushing to multiple EC2 instances on a load balancer


Yes, I do this all of the time (with the same application stack, actually).

  1. Use a base AMI from a trusted source, such as the default "Amazon Linux" ones, or roll your own.

  2. As part of the launch configuration, use the "user data" field to bootstrap a provisioning process on boot. This can be as simple as a shell script that runs yum install nginx php-fpm -y and copies files down from a S3 bucket or do a pull from your repo. The Amazon-authored AMI's also include support for cloud-init scripts if you need a bit more flexibility. If you need even greater power, you can use a change management and orchestration tool like Puppet, Chef, or Salt (my personal favorite).

  3. As far as updating code on existing instances: there are two schools of thought:

    • Make full use of the cloud and just spin up an entirely new fleet of instances that grab the new code at boot. Then you flip the load balancer to point at the new fleet. It's instantaneous and gives you a really quick way to revert to the old fleet if something goes wrong. Hours (or days) later, you then spin down the old instances.
    • You can use a tool like Fabric or Capistrano to do a parallel "push" deployment to all the instances at once. This is generally just re-executing the same script that the servers ran at boot. Salt and Puppet's MCollective also provide similar functionality that mesh with their basic "pull" provisioning.


Option one

  1. Push it to one machine.
  2. Have a git hook created on it http://git-scm.com/book/en/Customizing-Git-Git-Hooks.
  3. Make hook run pull on other machines.

Only problem , you'll have to maintain list of machines to run update on.

Another option

Have cron job to pull from your bitbucket account. on a regular base.


The tool for this job is Capistrano.

I use an awesome gem called capistrano-ec2group in order to map capistrano roles with EC2 security groups.

This means that you only need to apply an EC2 security group (eg. app-web or app-db) to your instances in order for capistrano to know what to deploy to them.

This means you do not have to maintain a list of server IPs in your app.

The change to your workflow would be that instead of focussing on automating the deploy on pushing to bitbucket, you would push and then execute

cap deploy

If you really don't want to do to steps, make an alias :D

alias shipit=git push origin master && cap deploy