Disclaimer: these code segments have not been really “tested” verbatim. I assume anyone who is successfully bundling EC2 images (that run) will know enough about copying shell scripts off blogs to test for typos, etc! Oh, and, sorry for lack of indentation on these… I’m just not taking the time 🙂
As I’ve been searching for a way of using ec2 in a production environment. To keep it as simple as possible, but also eliminate the need for unnecessary (and extremely tedious) image building both during and after the development process (development of the AMI, not the service). This is what I’ve come up with.
Step 1: our repository
Create a subversion repository which is web accessible and password protected (of course) like so:
- ami/trunk/init.sh
- ami/trunk/files/
- ami/tags/bootstrap.sh
- ami/tags/
ami/tags/bootstrap.sh would read:
#!/bin/bash
BootLocation=”ami/trunk”
BootHost=”svnhost.com”
BootUser=”userame”
BootPass=”password”
BootProtocol=”http”
## Prepare the bootstrap directory
echo -en “\tPreparing… ”
if [ -d /mnt/ami ]
then
rm -rf /mnt/ami
fi
mkdir -p /mnt/ami/
if [ $? -ne 0 ]; then exit $?; else echo “OK”; fi
## populating the bootstrap
echo -en “\tPopulating… ”
svn –force \
–username $BootUser \
–password $BootPass \
export \
$BootProtocol://$BootHost/$BootLocation/ \
/mnt/ami/ 1>/dev/null 2>/dev/null
if [ $? -ne 0 ]; then exit $?; else echo “OK”; fi
chmod a+x /mnt/ami/init.sh
## hand off
echo -e “\tHanding off to init script…”
/mnt/ami/init.sh
exit $?
ami/trunk/init.sh would read something like:
#!/bin/bash
## Filesystem Additions/Changes
echo -en “\t\tSynchronizing System Files… ”
cd /mnt/ami/files/
for i in $(find -type d)
do
mkdir -p “/$i”
done
echo -en “d”
for i in $(find -type f)
do
cp -f “$i” “/$i”
done
echo -en “f”
echo ” OK”
## Any Commands Go Here
## All Done!
exit 0
Step 2: configure your AMI
create /etc/init.d/servicename
chkconfig –add servicename
chkconfig –levels 345 servicename on
/etc/init.d/servicename should look something like:
#! /bin/sh
#
# chkconfig: – 85 15
# description: Ec2 Bootstrapping Process
#
RETVAL=0
case “$1” in
start)
/usr/bin/wget \
-o /dev/null -O /mnt/bootstrap.sh \
http://user:pass@svnhost/ami/tags/bootstrap.sh
/bin/bash /mnt/bootstrap.sh
RETVAL=$?
;;
stop)
exit 0
;;
restart)
$0 start
RETVAL=$?
;;
*)
echo “Usage: $0 {start|stop|restart}”
exit 1
;;
esac
exit $RETVAL
And now when the AMI boots itself up we hit 85 during runlevel 3 bootup (well after network initialization), servicename starts, and the bootstrapping begins. We’re then able, with our shell scripts, to make a great deal of changes to the system after the fact. These changes might be bugfixes, or they might be setup processes to reconstitute a database and download the latest code from a source control repository located elsewhere… They might be registration via a DNS API… anything at all.
The point is that some flexibility is needed, and this is one way to build that in!