Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Script to start an Amazon ElasticBeanstalk application with configuration parameters
#!/bin/sh
########################################################
# history
########################################################
#
# 0.3 (2011-02-08)
# - create/update configuration template 'InitialConfig' instead
# of 'Default', which is not editable
#
# 0.2 (2011-02-03)
# - check whether SSH key exists
# - create/update configuration template 'Default'
# if not explicitly specified. Previously, the
# configuration template was named identically to
# the environment
#
# 0.1 (2011-02-03)
# - initial release
# "global" vars
APP=
ENV=
TMPL=
APPFILE=
APPDESCR=
ENVDESCR=
IMAGEID=
INSTANCETYPE=
VERSION=
OPTIONS=
KEYNAME=
OPTFILE=
CNAME=
CONTAINER=
DEFAULT_TEMPLATE_NAME="InitialConfig" # "Default" is not editable
TMPOPTFILE=`mktemp -p "$TMPDIR" launcfg.XXXXXXX`
# Beanstalk app parameters
MIN_COUNT=1
MAX_COUNT=1
SECGROUP=
PARAM1=
PARAM2=
PARAM3=
PARAM4=
PARAM5=
JDBC_CONNECTION_STRING=
ERROR=1
WARN=2
INFO=3
DEBUG=4
LOGLEVEL=$WARN
######################################################################
# some functions
SCRIPTNAME=$(basename $0)
function usage() {
echo >&2 "usage: $SCRIPTNAME <options> -a appname {-e envname|-T template}"
echo >&2 " $SCRIPTNAME <options> -a appname -e envname"
echo >&2 " create and start an application"
echo >&2 " $SCRIPTNAME <options> -a appname -T template"
echo >&2 " create an application and a configuration template"
echo >&2 ""
echo >&2 " -a appname application name (required)"
# "{-e envname|-T template} [-f appfile] [-k keyname] [-i image-id] [-t image-type] [-v version]"
echo >&2 " -e environment Name of environment to create"
echo >&2 " -T template Name of configuration template to create"
echo >&2 " -d desciption application description"
echo >&2 " -D desciption environment/template description"
echo >&2 ""
echo >&2 "* Instance parameters"
echo >&2 " -i image-id AMI id"
echo >&2 " -t instance-type Instance type, e.g. 'm1.small' or 't1.micro'"
echo >&2 " -C solution-stack solution stack to use"
echo >&2 " possible values:"
echo >&2 " '32' -> 32bit Amazon Linux running Tomcat 6"
echo >&2 " '64' -> 64bit Amazon Linux running Tomcat 6"
echo >&2 " or any other solution stack as shown by"
echo >&2 " elastic-beanstalk-list-available-solution-stacks"
echo >&2 " -c CNAME CNAME to be used for the environment"
echo >&2 " if empty, the environment is used"
echo >&2 ""
echo >&2 "* Security parameters"
echo >&2 " -k keyname name of SSH access key configured in EC2"
echo >&2 " -g security-group security group to apply"
echo >&2 " -o optionsfile file containing additional options in JSON format"
# application parameters
echo >&2 ""
echo >&2 "* Application parameters"
echo >&2 " -V version label for application version"
echo >&2 " -f location S3 location of application WAR file."
echo >&2 " Format: 'bucket/file_key'"
echo >&2 " If version is specified, but location is empty,"
echo >&2 " the AWS sample application is used"
echo >&2 " -1 value PARAM1"
echo >&2 " -2 value PARAM2"
echo >&2 " -3 value PARAM3"
echo >&2 " -4 value PARAM4"
echo >&2 " -5 value PARAM5"
echo >&2 " -j value JDBC_CONNECTION_STRING"
# min, max instance count
echo >&2 ""
echo >&2 "* Load-balancing parameters"
echo >&2 " -m max-count max number of instances to create"
echo >&2 " -M min-count min number of instances to create"
echo >&2 ""
echo >&2 "* Other parameters"
echo >&2 " -h usage show this help"
echo >&2 " -v increase verbosity"
echo >&2 " -q decrease verbosity"
}
function log() {
local level=$1
shift
if [ "$level" -le "$LOGLEVEL" ]; then
echo >&2 "== " "$@"
fi
}
function isLevel() {
local level=$1
shift
if [ $level -le $LOGLEVEL ]; then
return 0
fi
return 1
}
function error() {
log $ERROR "$@"
}
function isError() {
isLevel $ERROR
}
function warn() {
log $WARN "$@"
}
function isWarn() {
isLevel $WARN
}
function info() {
log $INFO "$@"
}
function isInfo() {
isLevel $INFO
}
function debug() {
log $DEBUG "$@"
}
function isDebug() {
isLevel $DEBUG
}
function configOption() {
local namespace=$1
local name=$2
local value=$3
echo "{\"Namespace\":\"$namespace\",\"OptionName\":\"$name\",\"Value\":\"$value\"}"
}
function configure() {
local separator=","
while getopts "n" OPT $@; do
case "$OPT" in
n) separator=""
esac
done
# reset index, remove parsed args
optind=$OPTIND
unset OPTIND
if [ "$optind" -gt 0 ]; then
shift $((optind - 1))
fi
local file=$1
local namespace=$2
local name=$3
local value=$4
if [ -n "$value" ]; then
echo $(configOption "$namespace" "$name" "$value") $separator >> "$file"
fi
}
######################################################################
# parse options
while getopts "a:e:f:d:D:i:T:k:t:hv:Vqo:1:2:3:4:5:j:g:c:C:m:M:" OPT $@; do
case "$OPT" in
h) usage; exit 0;;
v) LOGLEVEL=$((LOGLEVEL + 1));;
q) LOGLEVEL=$((LOGLEVEL - 1));;
a) APP="$OPTARG";;
f) APPFILE="$OPTARG";;
# environment name
e) ENV="$OPTARG";;
d) APPDESCR="$OPTARG";;
D) ENVDESCR="$OPTARG";;
i) IMAGEID="$OPTARG";;
t) INSTANCETYPE="$OPTARG";;
V) VERSION="$OPTARG";;
k) KEYNAME="$OPTARG";;
T) TMPL="$OPTARG";;
o) OPTFILE="$OPTARG";;
# application parameters
1) PARAM1="$OPTARG";;
2) PARAM2="$OPTARG";;
3) PARAM3="$OPTARG";;
4) PARAM4="$OPTARG";;
5) PARAM5="$OPTARG";;
j) JDBC_CONNECTION_STRING="$OPTARG";;
g) SECGROUP="$OPTARG";;
c) CNAME="$OPTARG";;
# min, max instance count
m) MAX_COUNT="$OPTARG";;
M) MIN_COUNT="$OPTARG";;
# container
C) CONTAINER="$OPTARG";;
esac
done
# reset index, remove parsed args
optind=$OPTIND
unset OPTIND
if [ "$optind" -gt 0 ]; then
shift $((optind - 1))
fi
######################################################################
# validate args
# app name is required
if [ -z "$APP" ]; then
error "missing app name (paramater -a)"
exit 10
fi
if [ -z "$APPDESCR" ]; then
APPDESCR="$APP"
fi
# environment and/or template is required
if [ -z "$ENV" ]; then
if [ -z "$TMPL" ]; then
#error "missing environment or template name (paramater -e or -T)"
#exit 10
TMPL="$DEFAULT_TEMPLATE_NAME" # default configuration name is "Default"
fi
else
if [ -z "$TMPL" ]; then
# use environment name as template name
#TMPL="$ENV"
TMPL="$DEFAULT_TEMPLATE_NAME" # default configuration name is "Default"
fi
if [ -z "$CNAME" ]; then
CNAME="$ENV"
fi
fi
if [ -z "$ENVDESCR" ]; then
ENVDESCR="$ENV"
fi
if [ -z "$ENVDESCR" ]; then
ENVDESCR="$TMPL"
fi
# version is optional
if [ -z "$VERSION" ]; then
#VERSION=initial
VERSION=$(date +%Y%m%d-%H%M%S)
fi
# allow to choose between 32bit and 64 bit Tomcat container
case "$CONTAINER" in
64) CONTAINER="64bit Amazon Linux running Tomcat 6";;
32) CONTAINER="32bit Amazon Linux running Tomcat 6";;
esac
######################################################################
# perform actions
# check name of keypair
if [ -n "$KEYNAME" ]; then
# check whether ec2-describe-keypairs is available
if which ec2-describe-keypairs >/dev/null 2>&1 ; then
if ec2-describe-keypairs "$KEYNAME" >/dev/null 2>&1; then
debug "keypair $KEYNAME is valid"
else
error "keypair $KEYNAME does not exist"
exit 10
fi
fi
fi
# check whether application already exists
appCheck=$(elastic-beanstalk-describe-applications -a "$APP" | grep -iv "No applications found")
if [ -z "$appCheck" ]; then
info "creating app $APP"
elastic-beanstalk-create-application -a "$APP" -d "$APPDESCR"
RC=$?
debug "result of elastic-beanstalk-create-application: $RC"
if [ "$RC" -ne 0 ]; then
echo "failed to create application $APP"
exit $RC
fi
else
info "app $APP already exists"
fi
if [ -n "$APPFILE" -o -n "$VERSION" ]; then
# check whether app version already exists:
# list version (and remove headers and "no such version" warning)
versions=$(elastic-beanstalk-describe-application-versions -a "$APP" -l "$VERSION" | grep -Ev "were found|----|DateCreated")
if [ -z "$versions" ]; then
info "creating app $APP version $VERSION from ${APPFILE:-AWS sample application}"
# check whether APPFILE is a local file instead of S3 location
if [ -f "$APPFILE" ]; then
warn "$APPFILE is a local file, but a S3 location formatted as 'bucket/file_key' is expected!"
fi
elastic-beanstalk-create-application-version -a "$APP" -l "$VERSION" -s "$APPFILE"
RC=$?
debug "result of elastic-beanstalk-create-application-version: $RC"
if [ "$RC" -ne 0 ]; then
echo "failed to create application $APP version $VERSION from $APPFILE"
exit $RC
fi
else
# TODO update version if location differs
info "app $APP version $VERSION already exists"
fi
fi
# create temporary options file
TMPOPTFILE=`mktemp -p "$TMPDIR" launcfg.XXXXXXX`
debug "create temporary options file in $TMPOPTFILE"
# open options array
echo "[" > "$TMPOPTFILE"
if [ -f "$OPTFILE" ]; then
# add existing user options
cat "$OPTFILE" >> "$TMPOPTFILE"
fi
configure "$TMPOPTFILE" "aws:autoscaling:launchconfiguration" "ImageId" "$IMAGEID"
configure "$TMPOPTFILE" "aws:autoscaling:launchconfiguration" "SecurityGroups" "$SECGROUP"
configure "$TMPOPTFILE" "aws:autoscaling:launchconfiguration" "InstanceType" "$INSTANCETYPE"
configure "$TMPOPTFILE" "aws:autoscaling:launchconfiguration" "EC2KeyName" "$KEYNAME"
configure "$TMPOPTFILE" "aws:elasticbeanstalk:application:environment" "PARAM1" "$PARAM1"
configure "$TMPOPTFILE" "aws:elasticbeanstalk:application:environment" "PARAM2" "$PARAM2"
configure "$TMPOPTFILE" "aws:elasticbeanstalk:application:environment" "PARAM3" "$PARAM3"
configure "$TMPOPTFILE" "aws:elasticbeanstalk:application:environment" "PARAM4" "$PARAM4"
configure "$TMPOPTFILE" "aws:elasticbeanstalk:application:environment" "PARAM5" "$PARAM5"
configure "$TMPOPTFILE" "aws:elasticbeanstalk:application:environment" "JDBC_CONNECTION_STRING" "$JDBC_CONNECTION_STRING"
configure "$TMPOPTFILE" "aws:autoscaling:asg" "MaxSize" "$MAX_COUNT"
# add final param without trailing comma
configure -n "$TMPOPTFILE" "aws:autoscaling:asg" "MinSize" "$MIN_COUNT"
# close options array
echo "]" >> "$TMPOPTFILE"
# check whether app version already exists:
# NOTE we abuse elastic-beanstalk-describe-configuration-settings to check, whether the configuration template exists
templateCheck=$(elastic-beanstalk-describe-configuration-settings -a "$APP" -t "$TMPL"|head -1|grep -i "error")
if [ -n "$templateCheck" ]; then
info "creating configuration template $TMPL"
# error, create configuration template
if [ -n "$CONTAINER" ]; then
elastic-beanstalk-create-configuration-template -a "$APP" -t "$TMPL" -d "$ENVDESCR" -f "$TMPOPTFILE" -s "$CONTAINER"
else
elastic-beanstalk-create-configuration-template -a "$APP" -t "$TMPL" -d "$ENVDESCR" -f "$TMPOPTFILE"
fi
else
info "updating existing configuration template $TMPL"
# configuration template already exists, update it
if [ -n "$CONTAINER" ]; then
warn "cannot update solution stack for existing configuration template ($CONTAINER)"
fi
elastic-beanstalk-update-configuration-template -a "$APP" -t "$TMPL" -d "$ENVDESCR" -f "$TMPOPTFILE"
fi
RC=$?
debug "result of elastic-beanstalk-create-configuration-template: $RC"
# delete temporary options file
if [ -n "$TMPOPTFILE" -a -f "$TMPOPTFILE" ]; then
if isDebug; then
debug "options"
cat "$TMPOPTFILE"
fi
rm -f "$TMPOPTFILE"
fi
if [ "$RC" -ne 0 ]; then
error "failed to create configuration template"
exit $RC
fi
if [ -n "$ENV" ]; then
# check availablility of CNAME
checkDNS=$(elastic-beanstalk-check-dns-availability -c "$CNAME" | tail -1 | grep -i "true")
if [ -n "$checkDNS" ]; then
info "creating environment $ENV for app $APP version $VERSION"
elastic-beanstalk-create-environment -a "$APP" -l "$VERSION" -e "$ENV" -t "$TMPL" -c "$CNAME" -d "$ENVDESCR"
else
error "failed to create environment $ENV for app $APP version $VERSION: CNAME $CNAME is not available"
fi
fi
exit $RC
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.