Tuesday, June 09, 2009

Init script to mount EBS and attach elastic IPs to EC2 instances

Modified init script to mount EBS automatically to your EC2 instances.  It also dynamically attaches your instances to an elastic ip.  You have to provide both EBS volume id and elastic ip as userdata separated by pipe symbol for this script to work.  Sample userdata 

vol-12345678|171.213.234.123

You have to use 

update-rc.d mountec2vol start 47 S . stop 35 0 6 . start 37 6 .

to add this script to startup. This script also additional code to mount mysql data directory and nginx directories from EBS. You can skip that part.




#! /bin/sh
#
# /etc/init.d/mountec2vol
#
# chkconfig: 234 20 50
# description: Assigns an EC2 EBS Volume to a device and mounts the device
#
# To add this as a service run:
# /sbin/chkconfig --add mountec2vol
#
# VARS
#
DEV="/dev/sdh"
MOUNT_POINT="/vol"
EC2_LOG='/var/log/ec2.log';
SELF=$(cd $(dirname $0); pwd -P)/$(basename $0)

export JAVA_HOME=/usr/lib/jvm/java-6-sun-1.6.0.13/
export EC2_PRIVATE_KEY=/root/.ec2/pk.pem
export EC2_CERT=/root/.ec2/cert.pem
export EC2_HOME=/usr/local/src/ec2-api-tools-1.3-36506/
PATH=$PATH:$HOME/bin:$EC2_HOME/bin
MAX_TRIES=60

attach_ebs()
{
/bin/echo "=====================================" | tee -a $EC2_LOG
/bin/echo "Date: "`date` | tee -a $EC2_LOG;
/bin/echo "Attaching Elastic Block Store Volumes." | tee -a $EC2_LOG
ec2-attach-volume $VOL -i $INSTANCE -d $DEV 1>&2 2>>$EC2_LOG
CTR=0
while [ ! -e "$DEV" ]; do
/bin/sleep 1
CTR=`expr $CTR + 1`
if [ $CTR -eq $MAX_TRIES ]
then
/bin/echo "WARNING: Cannot attach volume $VOL to $DEV -- Giving up after $MAX_TRIES attempts" | tee -a $EC2_LOG
exit 1
fi
done
}
mount_ebs()
{
/bin/echo "Checking if $MOUNT_POINT is present" | tee -a $EC2_LOG
if [ ! -d $MOUNT_POINT ]; then
mkdir $MOUNT_POINT 1>&2 2>>$EC2_LOG
fi
/bin/echo "Mounting EBS to /vol " | tee -a $EC2_LOG
/bin/mount $DEV $MOUNT_POINT 1>&2 2>>$EC2_LOG
}
mount_mysql_dirs()
{
/bin/echo "Mounting mysql dirs" | tee -a $EC2_LOG
/bin/mount /etc/mysql/ 1>&2 2>>$EC2_LOG
/bin/mount /var/lib/mysql/ 1>&2 2>>$EC2_LOG
/bin/mount /var/log/mysql/ 1>&2 2>>$EC2_LOG
/bin/mount /usr/local/nginx/ 1>&2 2>>$EC2_LOG
}
unmount_mysql_dirs()
{
set +e;
/bin/echo "stopping mysql" | tee -a $EC2_LOG
/etc/init.d/mysql stop;
set -e;
/bin/echo "Unmounting mysql dirs" | tee -a $EC2_LOG
/bin/umount /etc/mysql/ 1>&2 2>>$EC2_LOG
/bin/umount /var/lib/mysql/ 1>&2 2>>$EC2_LOG
/bin/umount /var/log/mysql/ 1>&2 2>>$EC2_LOG
}
unmount_nginx_dirs()
{
set +e;
/bin/echo "stopping nginx" | tee -a $EC2_LOG
/etc/init.d/nginx stop;
set -e;
/bin/echo "Unmounting nginx dirs" | tee -a $EC2_LOG
/bin/umount /usr/local/nginx/ 1>&2 2>>$EC2_LOG
}
unmount_ebs()
{
/bin/echo "Unmounting Elastic Block Store Volumes." | tee -a $EC2_LOG
/bin/umount $MOUNT_POINT 1>&2 2>>$EC2_LOG
}
detach_ebs()
{
/bin/echo "Detaching Elastic Block Store Volumes." | tee -a $EC2_LOG
ec2-detach-volume $VOL 1>&2 2>>$EC2_LOG
}
populate_aws_data()
{
/bin/echo "Populating AWS data" | tee -a $EC2_LOG
INSTANCE=`curl http://169.254.169.254/latest/meta-data/instance-id 2> /dev/null`
USERDATA=`curl http://169.254.169.254/1.0/user-data 2>/dev/null`;
}
parse_user_args()
{
/bin/echo "Parsing user_args " | tee -a $EC2_LOG
VOL=${USERDATA%|*};
IP=${USERDATA#*|};
echo "usedata vol ip";
echo $USERDATA;
echo $VOL;
echo $IP;
}
bind_ip()
{
/bin/echo "Associating ip address: $IP to $INSTANCE" | tee -a $EC2_LOG
ec2-associate-address -i $INSTANCE $IP;
}

# start/stop functions for OS

case "$1" in

start)
populate_aws_data;
parse_user_args;
bind_ip;
attach_ebs;
mount_ebs;
mount_mysql_dirs;
sh -x /vol/ec2_stuff/everytime_by_mountec2.sh;
;;
stop)
unmount_mysql_dirs;
unmount_nginx_dirs;
unmount_ebs;
detach_ebs;
;;
restart)
set +e;
$SELF stop;
set -e;
sleep 60;
$SELF start
;;
*)
echo "Usage: $0 {start|stop|restart}" | tee -a $EC2_LOG
exit 1

esac

exit 0