Friday, 10 April 2015

AWS EC2 instance - Power off/on instance based on tag value

Cron job that runs every hour to check whether it needs to stop or start an instance based on Power_on_off tag

#!/bin/bash
# Power on and power off EC2-instance according to their Power_off_on tag

Current_hour=`date +%H`

PowerOff_check () {
Poweroff_hour=`/dir/.local/lib/aws/bin/aws ec2 describe-instances --instance-ids $instance |grep Power_off_on|awk '{ print $3 }'`
if [ -z $Poweroff_hour ]
then
    echo "No poweroff hour"
    exit
fi

echo "Server is $instance"

if [ $Current_hour -eq $Poweroff_hour ]
then
        echo "/dir/.local/lib/aws/bin/aws ec2 stop-instances --instance-ids $instance"
else
        echo "Current hour is not equal power off hour"
fi
}

PowerOn_check () {
Poweron_hour=`/dir/.local/lib/aws/bin/aws ec2 describe-instances --instance-ids $instance |grep Power_off_on|awk '{ print $4 }'`
if [ -z $Poweron_hour ]
then
    echo "No poweron hour"
    exit
fi

if [ $Current_hour -eq $Poweron_hour ]
then
        echo "/dir/.local/lib/aws/bin/aws ec2 start-instances --instance-ids $instance"
else
        echo "Current hour is not equal power on hour"
fi
}

LIST=`/dir/.local/lib/aws/bin/aws ec2 describe-instances --filters "Name=tag-key, Values=Power_off_on"|grep ^INSTANCES| awk '{ print $8 }'`
for instance in $LIST
do
   PowerOff_check
   PowerOn_check
done

Update: Schedule based on tags
Schedule:Sun:Mon 07.00 23:00:Tue 07.00 23.00:Wed 07.00 23.00:Thu 07.00 23.00:Fri 07.00 23.00:Sat:31.12.2100:r3.xlarge"

See pseudo code below:
lock=/var/log/awsscheduler.lock
(
email=cloudsupportteam@company.com
instances=/tmp/ec2instances
startstop=/tmp/ec2startstop
report=/tmp/awsscheduler-report
log=/var/log/awsscheduler.log

flock -x -w 10 201 || exit 1

aws ec2 describe-instances | jq -r  '.Reservations[].Instances[] | (.Tags | map(.value=.Value | .key=.Key) | from_entries) as $tags | "\(.InstanceId)#\(.InstanceType)#\(.PrivateIpAddress)#\(.PublicIpAddress)#\(.PublicDnsName)#\(.State.Name)#\(.Platform)#\(.LaunchTime)#\(.VpcId)#\(.SubnetId)#\(.Placement.AvailabilityZone)#\(.KeyName)#\(.ImageId)#\(.VirtualizationType)#\(.Monitoring.State)#\(.BlockDeviceMappings[0].Ebs.VolumeId)#\(.BlockDeviceMappings[1].Ebs.VolumeId)#\(.BlockDeviceMappings[2].Ebs.VolumeId)#\(.BlockDeviceMappings[3].Ebs.VolumeId)#\(.BlockDeviceMappings[4].Ebs.VolumeId)#\(.BlockDeviceMappings[5].Ebs.VolumeId)#\(.BlockDeviceMappings[6].Ebs.VolumeId)#\(.BlockDeviceMappings[7].Ebs.VolumeId)#\(.BlockDeviceMappings[8].Ebs.VolumeId)#\(.BlockDeviceMappings[9].Ebs.VolumeId)#\(.SecurityGroups[0].GroupId)#\(.SecurityGroups[1].GroupId)#\(.SecurityGroups[2].GroupId)#\(.SecurityGroups[3].GroupId)#\(.SecurityGroups[4].GroupId)#\($tags.Name)#\($tags.Product)#\($tags.Bu)#\($tags.Environment)#\($tags.Owner)#\($tags.Cc)#\($tags.Service)#\($tags["aws:cloudformation:stack-name"])"'  2>/dev/null |  tr ',' ';' | tr '#' ',' > $instances

d=`TZ='Australia/Sydney' date +%a.%H.%M`
#d=`Mon.09.57
today=`echo $d | cut -d'.' -f1`

> $startstop
# Loop through all instances
while read line; do
        i=`echo $line |  cut -d',' -f2`
        s=`echo $line |  cut -d',' -f20`
        #s="Schedule:Sun:Mon 07.00 23:Tue 07.00 23.00:Wed 07.00 23.00:Thu 07.00 23.00:Fri 07.00 23.00:Sat:31.12.2100:r3.xlarge"

        case "$today" in
        Sun) t=`echo $s | cut -d':' -f2`
            ;;
        Mon) t=`echo $s | cut -d':' -f3`
            ;;
        Tue) t=`echo $s | cut -d':' -f4`
            ;;
        Wed) t=`echo $s | cut -d':' -f5`
           ;;
        Thu) t=`echo $s | cut -d':' -f6`
           ;;
        Fri) t=`echo $s | cut -d':' -f7`
           ;;
        Sat) t=`echo $s | cut -d':' -f8`
           ;;
        *) echo "Day $today is not processed"
           ;;
        esac

        startstop=`echo $t | sed -e 's/ /./' | sed -e "s/ /,$today./"`
        echo "$i,$startstop" >> $startstop
done < $instances

# $startstop
#i-123,Wed.07.00,Wed.23.00
#startinstances=`grep ",$d," $startstop | cut -d',' -f1 | tr '\n' ' '`
#stopinstances=`grep ",${d}$" $startstop | cut -d',' -f1 | tr '\n' ' '`
# [ -z "$startinstances" ] && aws ec2 start-instances --instance-ids $startinstances
# [ -z "$stopinstances" ] && aws ec2 stop-instances --instance-ids $startinstances
> $report
for instance in `cat $startstop | grep $d`
do
   echo "Instance: $instance"
   i=`echo $instance |  cut -d',' -f1`
   start=`echo $instance |  cut -d',' -f2`
   stop=`echo $instance |  cut -d',' -f3`
   [ "$start" == "$d" ] && echo "aws ec2 start-instances --instance-ids $i"
   [ "$stop" == "$d" ] && echo "aws ec2 stop-instances --instance-ids $i"
done > $report
if [ -s $report ]
then
  cat $report | mailx -s "AWS scheduler started/stopped instance(s) `date`" $email
fi
cat $report >> $log

) 201>$lock

No comments:

Post a Comment