#!/bin/bash - # Author: Colin Johnson / colin@cloudavail.com # Date: 2012-02-27 # Version 0.5 # License Type: GNU GENERAL PUBLIC LICENSE, Version 3 # ##### #as-update-launch-config start #gets an AMI from set of inputs getimageidcurl() { #get list of AMIs - format is region,bitdepth,storage,ami-id, -s is required to prevent curl from outputing progress meter to stderr amimap=`curl -s ${awsec2amimap}` #gets instanceid from downloaded file imageid=`echo "$amimap" | grep "$region,$bits,$storage" | cut -d ',' -f4` echo "AMI ID $imageid will be used for the new Launch Configuration. Note that as-update-launch-config uses Amazon Linux AMIs by default." } #determines that the user provided AMI does, in fact, exit imageidvalidation() { #amivalid redirects stderr to stdout - if the user provided AMI does not exist, the if statement will exit as-update-launch-config.sh else it is assumed that the user provided AMI exists amivalid=`ec2-describe-images $imageid --region $region 2>&1` if [[ $amivalid =~ "Client.InvalidAMIID.NotFound" ]] then echo "The AMI ID $imageid could not be found. If you specify an AMI (-m) it must exist and be in the given region (-r). Note that region (-r defaults to \"us-east-1\" if not given." 1>&2 ; exit 64 else echo "The user provided AMI \"$imageid\" will be used when updating the Launch Configuration for the Auto Scaling Group \"$asgroupname.\"" fi } #confirms that executables required for succesful script execution are available prerequisitecheck() { for prerequisite in basename cut curl date head grep as-update-auto-scaling-group as-describe-launch-configs as-describe-auto-scaling-groups ec2-describe-images do #use of "hash" chosen as it is a shell builtin and will add programs to hash table, possibly speeding execution. Use of type also considered - open to suggestions. hash $prerequisite &> /dev/null if [[ $? == 1 ]] #has exits with exit status of 70, executable was not found then echo "In order to use `basename $0`, the executable \"$prerequisite\" must be installed." 1>&2 ; exit 70 fi done } #calls prerequisitecheck function to ensure that all executables required for script execution are available prerequisitecheck #sets as-update-launch-config Defaults awsec2amimap="http://s3.amazonaws.com/colinjohnson-cloudavailprd/aws-ec2-ami-map.txt" region="us-east-1" dateymd=`date +"%F"` #handles options processing while getopts :a:i:u:b:s:p:r:m: opt do case $opt in a) asgroupname="$OPTARG";; i) instancetype="$OPTARG";; u) userdata="$OPTARG";; b) bits="$OPTARG";; s) storage="$OPTARG";; p) preview="$OPTARG";; r) region="$OPTARG";; m) imageid="$OPTARG";; *) echo "Error with Options Input. Cause of failure is most likely that an unsupported parameter was passed or a parameter was passed without a corresponding option." 1>&2 ; exit 64 ;; esac done #sets previewmode - will echo commands rather than performing work case $preview in true|True) previewmode="echo"; echo "Preview Mode is set to $preview" 1>&2 ;; ""|false|False) previewmode="";; *) echo "You specified \"$preview\" for Preview Mode. If specifying a Preview Mode you must specific either \"true\" or \"false.\"" 1>&2 ; exit 64 ;; esac # instance-type validator case $instancetype in t1.micro|m1.small|c1.medium|m1.medium) bits=$bits ; # bit depth validator for micro to medium instances - demands that input of bits for micro to medium size instances be 32 or 64 bit if [[ $bits -ne 32 && bits -ne 64 ]] then echo "You must specify either a 32-bit (-b 32) or 64-bit (-b 64) platform for the \"$instancetype\" EC2 Instance Type." 1>&2 ; exit 64 fi ;; m1.large|m1.xlarge|m2.xlarge|m2.2xlarge|m2.4xlarge|c1.xlarge|cc1.4xlarge) bits=64;; "") echo "You did not specify an EC2 Instance Type. You must specify a valid EC2 Instance Type (example: -i m1.small or -i m1.large)." 1>&2 ; exit 64;; *) echo "The \"$instancetype\" EC2 Instance Type does not exist. You must specify a valid EC2 Instance Type (example: -i m1.small or -i m1.large)." 1>&2 ; exit 64;; esac # user-data validator if [[ ! -f $userdata ]] then echo "The user-data file \"$userdata\" does not exist. You must specify a valid user-data file (example: -u /path/to/user-data.txt)." 1>&2 ; exit 64 fi # storage validator case $storage in ebs|EBS) storage=EBS;; s3|S3) storage=S3;; "") storage=EBS ;; # if no storage type is set - default to EBS *) echo "The \"$storage\" storage type does not exist. You must specify a valid storage type (either: -s ebs or -s s3)." 1>&2 ; exit 64;; esac # region validator case $region in us-east-1|us-west-2|us-west-1|eu-west-1|ap-southeast-1|ap-northeast-1|sa-east-1|ap-southeast-2) ;; *) echo "The \"$region\" region does not exist. You must specify a valid region (example: -r us-east-1 or -r us-west-2)." 1>&2 ; exit 64;; esac # as-group-name validator - need to also include "command not found" if as-describe-auto-scaling-groups doesn't fire if [[ -z $asgroupname ]] then echo "You must specify an Auto Scaling Group name (example: -a asgname)." 1>&2 ; exit 64 fi #creates list of Auto Scaling Groups asgresult=`as-describe-auto-scaling-groups $asgroupname --show-long --region $region --max-records 1000` #user response for Auto Scaling Group lookup - alerts user if Auto Scaling Group was not found. if [[ $asgresult = "No AutoScalingGroups found" ]] then echo "The Auto Scaling Group named \"$asgroupname\" does not exist. You must specify an Auto Scaling Group that exists." 1>&2 ; exit 64 fi #if $imageid has a length of non-zero call imageidvalidation else call getimageid. if [[ -n $imageid ]] then imageidvalidation else getimageidcurl fi #gets current launch-config launch_config_current=`echo $asgresult | head -n 1 | cut -d ',' -f3` aslcresult=`as-describe-launch-configs $launch_config_current --show-long --region $region --max-records 1000` launch_config_security_group=`echo $aslcresult | cut -d ',' -f9` launch_config_key=`echo $aslcresult | cut -d ',' -f5` echo "The Auto Scaling Group \"$asgroupname\" uses the security group \"$launch_config_security_group\"." 1>&2 echo "The Auto Scaling Group \"$asgroupname\" uses the key \"$launch_config_key.\"" 1>&2 #code below searches for unique identifier for launch-config - without a unique identifier, launch config creation would fail. unique_lc_name_found=0 lc_uniq_id=1 aslc_list=`as-describe-launch-configs --show-long --region $region --max-records 1000 | cut -d ',' -f2` while [[ $unique_lc_name_found < 1 ]] do #tests if launch-config name will be unique if [[ $aslc_list =~ "$asgroupname-$dateymd-id-$lc_uniq_id" ]] then lc_uniq_id=$((lc_uniq_id+1)) else unique_lc_name_found=1 ; #for testing "Launch Condifuration Named: \"$asgroupname-$dateymd-id-$lc_uniq_id.\"" fi done launchconfig_new="$asgroupname-$dateymd-id-$lc_uniq_id" echo "A new Launch Configuration named \"$launchconfig_new\" for Auto Scaling Group \"$asgroupname\" will be created using EC2 Instance Type \"$instancetype\" and AMI \"$imageid.\"" #Create Launch Config $previewmode as-create-launch-config $launchconfig_new --image-id $imageid --instance-type $instancetype --region $region --group $launch_config_security_group --key $launch_config_key --user-data-file $userdata # #Update Auto Scaling Group $previewmode as-update-auto-scaling-group $asgroupname --region $region --launch-configuration $launchconfig_new