Updated bash script 23/01/2010: The script was assumed to run from EC2 itself, however I have since modified this so its applicable to local environments and made a little more robust.

There are quite a number of new tools from EC2, each requiring some form of setup on the server. As a result I have created a bash script to install them automatically.

  • AMI Tools
  • API Tools
  • Elastic Load Balancing Tools
  • Cloud Watch Tools

The only prerequisite is to install the certificate and private key within ~/.ec2/pk.pem and ~/.ec2/cert.pem and Java if on Fedora.

I have tested this on Debian and Fedora, which uses either yum or apt to execute the install of some dependencies, although it does assume that you are running under root.

You can download it from here ec2.sh

#!/bin/bash

DEBUG=1;

if [ "$(id -u)" != "0" ]; then
  echo "This script must be run as root" 1>&2
  exit 1
fi

GREP="`which grep`";
if which apt-get >/dev/null; then
  PACKAGE_MANAGEMENT="`which apt-get` "
else
  PACKAGE_MANAGEMENT="`which yum`"
fi

if which dpkg >/dev/null; then
  PACKAGE_TEST="dpkg --get-selections | $GREP -q "
else
  PACKAGE_TEST="rpm -qa | $GREP -q "
fi

CURL_OPTS=" --silent --retry 1 --retry-delay 1 --retry-max-time 1 "

function log
{
  if [ "$DEBUG" -eq 1 ]; then
    echo $1;
  fi;
}

function bail
{
  echo -e $1;
  exit 1;
}

function check_env
{
  if [ -f ~/.bashrc ]; then
    . ~/.bashrc;
  fi

  # Tools already exist
  if [ -z `which ec2-describe-instances` ] || [ -z `which ec2-upload-bundle` ] || [ -z `which ec2-describe-instances` ] || [ -z `which elb-create-lb` ] || [ -z `which mon-get-stats` ] || [ -z `which as-create-auto-scaling-group` ]; then
    log "Amazon EC2 toolkit missing!"
    install_ec2;
  fi

  # EC2_HOME set
  if [ -z "$EC2_HOME" ]; then
    log "Amazon EC2 is not set-up correctly! EC2_HOME not set"
    if ! grep EC2_HOME ~/.bashrc; then
      echo "export EC2_HOME=/usr/local/ec2-api-tools/" >> ~/.bashrc
    fi;
    export EC2_HOME=/usr/local/ec2-api-tools/
    source ~/.bashrc
  fi

  # Java
  if [ -z "$JAVA_HOME" ]; then

    if grep -i yum "$PACKAGE_MANAGEMENT" > /dev/null; then
      bail "nPlease install java manually (do not use yum install java, it is incompatible)nsee JRE http://java.sun.com/javase/downloads/index.jspnDownload, run the bin file, place in /opt/ and update ~/.bashrc. Once complete run 'source ~/.bashrc;'";
    fi;

    $PACKAGE_MANAGEMENT install -y sun-java6-jdk
    JAVA_PATH=/usr/lib/jvm/java-6-sun/jre/;

    echo "export JAVA_HOME=$JAVA_PATH" >> ~/.bashrc
    export JAVA_HOME=$JAVA_PATH
    source ~/.bashrc
  fi

  # Keys
  EC2_HOME_DIR='.ec2';
  EC2_PRIVATE_KEY_FILE="$HOME/$EC2_HOME_DIR/pk.pem";
  EC2_CERT_FILE="$HOME/$EC2_HOME_DIR/cert.pem";

  if [ ! -d "$HOME/$EC2_HOME_DIR" ]; then
    mkdir -pv "$HOME/$EC2_HOME_DIR";
  fi

  install_ec2_env EC2_PRIVATE_KEY "$EC2_PRIVATE_KEY_FILE";
  install_ec2_env EC2_CERT        "$EC2_CERT_FILE";

  install_ec2_keys_files "$EC2_PRIVATE_KEY_FILE" "Private key";
  install_ec2_keys_files "$EC2_CERT_FILE" "Certificate";

  install_ec2_env AWS_AUTO_SCALING_HOME "/usr/local/ec2-as-tools/"
  install_ec2_env AWS_ELB_HOME          "/usr/local/ec2-elb-tools/"
  install_ec2_env AWS_CLOUDWATCH_HOME   "/usr/local/ec2-cw-tools/"

  get_region
  get_availability_zone

}

function install_ec2_env
{
  # Variable Variable for $1
  EC2_VARIABLE=${!1};
  EC2_VARIABLE_NAME=$1;
  EC2_FILE=$2;

  #log "VARIABLE: $EC2_VARIABLE_NAME=$EC2_VARIABLE";

  # Variable Variable
  if [ -z "$EC2_VARIABLE" ]; then
    log "Amazon $EC2_VARIABLE_NAME is not set-up correctly!";

    if ! grep -q "$EC2_VARIABLE_NAME" ~/.bashrc > /dev/null; then
      echo "export $EC2_VARIABLE_NAME=$EC2_FILE" >> ~/.bashrc;
    fi;
    export $EC2_VARIABLE_NAME=$EC2_FILE;
    source ~/.bashrc
  else
    if ! grep -q "$EC2_VARIABLE_NAME" ~/.bashrc > /dev/null; then
      echo "export $EC2_VARIABLE_NAME=$EC2_FILE" >> ~/.bashrc;
    else
      log "Amazon $EC2_VARIABLE_NAME var installed";
    fi;
  fi
}

function install_ec2_keys_files
{
  EC2_FILE=$1;
  EC2_DESCRIPTION=$2;
  EC2_CONTENTS='';

  if [ ! -f "$EC2_FILE" ]; then
    bail "Amazon $EC2_FILE does not exist, please copy your $EC2_DESCRIPTION to $EC2_FILE and re-run this script";
  else
    log "Amazon $EC2_FILE file installed";
  fi
}

function install_ec2
{

  for PACKAGE in curl wget tar bzip2 unzip zip symlinks unzip ruby; do
    if ! which "$PACKAGE" >/dev/null; then
      $PACKAGE_MANAGEMENT install -y $PACKAGE;
    fi
  done;

  # AMI Tools
  if [ -z "`which ec2-upload-bundle`" ]; then
    curl -o /tmp/ec2-ami-tools.zip $CURL_OPTS --max-time 30 http://s3.amazonaws.com/ec2-downloads/ec2-ami-tools.zip
    rm -rf /usr/local/ec2-ami-tools;
    cd /usr/local && unzip /tmp/ec2-ami-tools.zip
    ln -svf `find . -type d -name ec2-ami-tools*` ec2-ami-tools
    chmod -R go-rwsx ec2* && rm -rvf /tmp/ec2*
  fi

  # API Tools
  if [ -z "`which ec2-describe-instances`" ]; then
    log "Amazon EC2 API toolkit is not installed!"
    curl -o /tmp/ec2-api-tools.zip $CURL_OPTS --max-time 30 http://s3.amazonaws.com/ec2-downloads/ec2-api-tools.zip
    rm -rf /usr/local/ec2-api-tools;
    cd /usr/local && unzip /tmp/ec2-api-tools.zip
    ln -svf `find . -type d -name ec2-api-tools*` ec2-api-tools
    chmod -R go-rwsx ec2* && rm -rvf /tmp/ec2*
  fi

  # ELB Tools
  if [ -z "`which elb-create-lb`" ]; then
    curl -o /tmp/ec2-elb-tools.zip $CURL_OPTS --max-time 30 http://ec2-downloads.s3.amazonaws.com/ElasticLoadBalancing-2009-05-15.zip
    rm -rf /usr/local/ec2-elb-tools;
    cd /usr/local && unzip /tmp/ec2-elb-tools.zip
    mv ElasticLoadBalancing-1.0.3.4 ec2-elb-tools-1.0.3.4;
    ln -svf `find . -type d -name ec2-elb-tools*` ec2-elb-tools
    chmod -R go-rwsx ec2* && rm -rvf /tmp/ec2*
  fi

  # Cloud Watch Tools
  if [ -z "`which mon-get-stats`" ]; then
    curl -o /tmp/ec2-cw-tools.zip $CURL_OPTS --max-time 30 http://ec2-downloads.s3.amazonaws.com/CloudWatch-2009-05-15.zip
    rm -rf /usr/local/ec2-cw-tools;
    mv -v CloudWatch-1.0.2.3 ec2-cw-tools-1.0.2.3
    cd /usr/local && unzip /tmp/ec2-cw-tools.zip
    ln -svf `find . -type d -name ec2-cw-tools*` ec2-cw-tools
    chmod -R go-rwsx ec2* && rm -rvf /tmp/ec2*
  fi

  if [ -z "`which as-create-auto-scaling-group`" ]; then
    curl -o /tmp/ec2-as-tools.zip $CURL_OPTS --max-time 30 http://ec2-downloads.s3.amazonaws.com/AutoScaling-2009-05-15.zip
    rm -rf /usr/local/ec2-as-tools;
    mv -v AutoScaling-1.0.9.0 ec2-as-tools-1.0.9.0
    cd /usr/local && unzip /tmp/ec2-as-tools.zip
    ln -svf `find . -type d -name ec2-as-tools*` ec2-as-tools
    chmod -R go-rwsx ec2* && rm -rvf /tmp/ec2*
  fi

  ln -sf /usr/local/ec2-api-tools/bin/* /usr/bin/;
  ln -sf /usr/local/ec2-ami-tools/bin/* /usr/bin/;
  ln -sf /usr/local/ec2-elb-tools/bin/* /usr/bin/;
  ln -sf /usr/local/ec2-cw-tools/bin/* /usr/bin/;
  ln -sf /usr/local/ec2-as-tools/bin/* /usr/bin/;

  rm -f /usr/bin/ec2-*.cmd;

}

function get_availability_zone
{
  # Not reliable between availability zones using meta-data
  # export EC2_AVAILABILITY_ZONE="`curl $CURL_OPTS --max-time 2 http://169.254.169.254/2009-04-04/meta-data/placement/availability-zone`"

  get_instance_id;

  if [ ! -z "$EC2_INSTANCE_ID" ]; then
    EC2_AVAILABILITY_ZONE="`ec2-describe-instances | grep -q $EC2_INSTANCE_ID | awk '{print $11}'`"
    if [ -z "$EC2_AVAILABILITY_ZONE" ] && [ ! "$EC2_AVAILABILITY_ZONE"="" ]; then
      export EC2_AVAILABILITY_ZONE=$EC2_AVAILABILITY_ZONE;
      install_ec2_env EC2_AVAILABILITY_ZONE $EC2_AVAILABILITY_ZONE;
    fi;
  fi;
}

function get_region
{
  get_instance_id;
  if [ ! -z "$EC2_INSTANCE_ID" ]; then
    EC2_REGION="`ec2-describe-instances | grep $EC2_INSTANCE_ID | awk '{print $11}'`"
    if [ -z "$EC2_REGION" ]; then
      export EC2_REGION=$EC2_REGION;
      install_ec2_env EC2_REGION $EC2_REGION;
      install_ec2_env EC2_URL "https://ec2.$EC2_REGION.amazonaws.com" | sed 's/a.amazonaws.com/.amazonaws.com/'
    fi;
  fi;
}

function get_instance_id
{
  instanceId="`curl $CURL_OPTS --max-time 2 http://169.254.169.254/1.0/meta-data/instance-id`"
  if [ ! -z "$instanceId" ]; then
    export EC2_INSTANCE_ID="$instanceId";
  fi;
}

check_env