I came across a problem recently when setting up some Fedora 8 Linux machine instances (AMIs) on Amazon’s EC2 service regarding the setting of the machine’s /etc/hosts file. The main issue was to get the host file to correlate the machine’s local IP address with its (new) host name. Seeing as the IP address was likely to be dynamic, I wanted to find a way of making sure that the current local IP was in that file each time the machine started.
The Script
Luckily, AWS provides a static address at which one can get metadata relating to the instance one is running (see references at base of post). So I set set about writing the script below. I wrote it in the style of a service so that I could get it to run at boot time and shutdown time.
#! /bin/sh
# set some vars/env vars up
HFILE=/etc/hosts
HNAME_S=`/bin/hostname -s`
HNAME_F=`/bin/hostname -f`
TDATE=`/bin/date "+%Y-%m-%d %H:%M:%S"`
export JAVA_HOME=/usr/java/default
export EC2_PRIVATE_KEY=/tmp/.ec2/your-key.pem
export EC2_CERT=/tmp/.ec2/your-cert.pem
export EC2_HOME=/root/ec2/
# optional, depending on your location (default is us-east)
export EC2_URL=http://eu-west-1.ec2.amazonaws.com
PATH=$PATH:$HOME/bin:$EC2_HOME/bin
MAX_TRIES=60
# start/stop functions for OS
start() {
# get ip address from api
ADD=`/usr/bin/curl http://169.254.169.254/latest/meta-data/local-ipv4 2> /dev/null`
CTR=0
/usr/bin/printf "Getting local ip address.\n";
# now check var for not being dotted quad format
while [[ ! "$ADD" =~ ^\([0-9]\{1,3\}\.\)\{3\}[0-9]\{1,3\}$ ]]; do
/bin/sleep 1
CTR=`expr $CTR + 1`
# if CTR has reached MAX_TRIES then bin out
if [ $CTR -eq $MAX_TRIES ]; then
/usr/bin/printf "WARNING: Cannot write $ADD to $HFILE -- Giving up after $MAX_TRIES attempts\n"
exit 1
fi
done
# if we get here $ADD is ok, so add required values to hosts file
/usr/bin/printf "# File written by /etc/init.d/getipadd at: $TDATE\n" > $HFILE
/usr/bin/printf "127.0.0.1\tlocalhost.localdomain\tlocalhost\n" >> $HFILE
/usr/bin/printf "$ADD\t$HNAME_F\t$HNAME_S\n" >> $HFILE
}
stop() {
# set host file to original value
/usr/bin/printf "# File written by /etc/init.d/getipadd\n at: $TDATE" > $HFILE
/usr/bin/printf "127.0.0.1\tlocalhost.localdomain\tlocalhost\n" >> $HFILE
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
stop
sleep 5
start
;;
*)
echo "Usage: $0 {start|stop|restart}"
exit 1
esac
exit 0
I am sure that there are a few things that could be done in order to improve the above script. For instance, the ip address checking could be more thorough; the script could be made to log more interesting information upon failure and so on…
First Run, Setup and Getting it running as a Service
Not too difficult. Just follow these steps; First move the script to the right place in the file system:
# mv getipadd /etc/init.d/
Then make it read/write/executable by root only:
# chmod 700 /etc/init.d/getipadd
Now it’s time to run it manually and check the hosts file:
# /etc/init.d/./getipadd start # cat /etc/hosts # File written by /etc/init.d/getipadd at: 2009-08-26 05:53:48 127.0.0.1 localhost.localdomain localhost 10.227.2.182 ip-10-227-2-182.eu-west-1.compute.internal ip-10-227-2-182
As can be seen, the host name and domain are the ones set by default when starting the instance. Next to modify /etc/sysconfig/network to add the HOSTNAME line:
NETWORKING=yes HOSTNAME=mine.mydomain.com
Then add that host info to the /etc/hosts file also:
# File written by /etc/init.d/getipadd at: 2009-08-26 05:53:48 127.0.0.1 localhost.localdomain localhost 10.227.2.182 mine.mydomain.com mine
Next, add the file into the service list using chkconfig (makes the service turn on at run levels 2, 3 and 4):
# chkconfig --level 234 getipadd on
To test, reboot the machine and check out the contents of /etc/hosts.
Of course, do not forget to re-bundle your machine image if you want this to be working beyond shutting down the machine.
References
No Comments on “Dynamically Populate /etc/hosts in an AWS AMI”
You can track this conversation through its atom feed.