AWS: VPC: Autoscaling and Deployment

The problems

1.  Distributing code to autoscaled EC2 instances without user interaction .

2.  Launching new instances with the current code release.

(Please do not use any code in this article without proper testing in a non-production environment!)

Solution

An architecture based upon EBS snapshots, rsync, the EC2 and Autoscaling api tools.

Overview

Problem 1.  Publishing code to existing instances

sync

Application code is stored on release server, on a dedicated EBS volume.

The deployment script performs the following operations:

1. Obtain list of instances in Autoscaling group(s)

2. Push application code from /release autoscaled instances.

3. Snapshot the underlying EBS volume and save the snapshot id for instances launched later.

Problem 2:  Launching instances with the correct code

UNIX system init script running on the new instance performs the following steps:

If /release is not already configured:

  1. Query http://releasesrvr/snap.txt for the latest snapshot id
  2. Create a new EBS volume based upon this snapshot
  3. Mount the new volume at /release
  4. Continue with boot process

Examples

Release server setup

1. Configure EC2, Autoscaling tools. Open HTTP port 80. Install and enable apache.

iptables -I INPUT -m tcp -p tcp --dport 80 -j ACCEPT
service iptables save
yum -y install httpd
chkconfig httpd on
service httpd start

2. Create volume

ec2-create-volume --region us-east-1 -z us-east-1b -s 40

3. Attach volume

ec2-attach-volume --region us-east-1 -d /dev/sdk1 --instance i-12345678 vol-12345678

4. Format volume

mkfs.ext3 -L code_release /dev/sdk1

5. Mount volume

echo "" >>/etc/fstab
echo "LABEL=code_release /release ext3 defaults 0 0" >>/etc/fstab
mount /release

6. Copy code

rsync -az stagecode:/release /release

7. Snapshot the volume

ec2-create-snapshot -d latestrelease vol-12345678 | awk '{print $2}' >/var/www/html/snap.txt

Deployment pseudocode

#!/bin/bash
# push code to autoscaled instances
SRC=/release/
DEST=/release/
KEY=/root/test.pem
LIST=instances.txt
>$LIST

sync;sync;sync;sleep 2 # flush buffers to disk

for i in `as-describe-auto-scaling-instances |awk '{print $2}'`; do
   ec2-describe-instances $i |grep INSTANCE|awk '{print $12}' >>$LIST;
done

for i in `cat $LIST`; do
   echo "Syncing from $SRC to $i:$DEST";
   rsync -av --delete -e "ssh -i$KEY"  $SRC www@$i:$DEST;
done

Boot pseudocode

#!/bin/bash
# create release filesystem at boot
DEV=/dev/sdk1

if ! grep “/release” /etc/fstab ; then
   VOL=`curl http://releasesrvr/snap.txt`
   VOL_ID=`ec2-create-volume --snapshot $VOL | awk '{print $2'}`
   ec2-attach-volume $VOL -i $myinstance -d $DEV
while [ ! -e $DEV ]; do
   sleep 5;
   let i++
   if [ $i -gt 10 ]; then
      echo "exceeded attempts waiting for device $DEV"
      exit 1
   fi
fi

Caveats

You must configure both the ec2 and autoscaling api tools as a prerequisite.

This process may not be well suited for publishing data that changes frequently.

In an ideal world, the /release volume on the deployment host would be unmounted before snapshotting.

There is a potential race condition here if code is being published during an autoscale event.

Programming examples have been simplified for clarity.   An implementation of this architecture will require a non-trivial amount of code and operating system knowledge..

Please remember that most ec2/autoscaling commands accept --region REGION .

 

 

 

Leave a Reply

Your email address will not be published. Required fields are marked *