-->

Friday, June 1, 2018

Starting and Stopping Ec2 instances Automatically during Night for Non-prod Environment for Saving on the AWS Billing

The following script can be used to start and stop the Ec2 instances during the non-productive ours for the lower environment such as Development, Sit, stage etc. Depending on the number of instances that are stopped you can save on your AWS Billing.

You can align the script to run during the defined ours using Cron job. The advantage of the script is that everytime you need to add an server to automatically start and stop you just need to enter in the Tag with specified values in our case its ADMIN_EC2_STARTSTOP which can have the values of stop or start and it would automatically add the instance to this setup. You don't have to change the script everytime a new server is being created.

The script uses an additional tag of Environment to identify the Environment to start and stopped as it can be possible that you want to stop the Stage and Dev environment at different times and different days depending upon your requirement. So you dont have to change the script same script can achieve this task.

Lastly script uses the key as same environment has same key usually to identify the name of the instance. though its possible to tweak this into the script to identify the name of the instance depending on the instance id.


 #!/bin/bash  
 #  
 #  
 # This script can be used for performing start/stop of ec2 instances. We can schedule the script using crontab for performing schedule based start/stop operations  
 #  
 # We can pass filters (only Key type) in order to filter out ec2 instance before performing start/stop operations  
 #  
 # Requirements:  
 # * The script works with ec2 instances which have the following Tag (Key=Value)  
 #    ADMIN_EC2_STARTSTOP=[Yes = Auto Start/Stop Enabled | No = Auto Start/Stop Disabled]  
 #  
 #  
 #  
 OUTPUT=text;  
 FILTER='"Name=tag:ADMIN_EC2_STARTSTOP,Values=Yes"';  
 # We need to provide the name of the Environment and  
 # action to perform  
 #  
 usage(){  
     echo -e "Usage:\n";  
     echo -e "$0 <start|stop> [Environment Name] \n";  
     echo "Examples:";  
     echo 'Starting All Instances in Stage Environment"';  
     echo " # $0"' Start Stage';  
     exit 0;  
 }  
 # Two inputs required to execute the script  
 if [ $# -ne 2 ];  
 then  
     usage;  
 fi;  
 # Check if valid action is provided for the script  
 ACTION=$1;  
 if [[ $ACTION != "start" && $ACTION != "stop" ]];# && $1 != "stop" ];  
 then  
     usage;  
 fi;  
 ENVIRONMENT=$2;  
 echo "Environment : $ENVIRONMENT"  
 # Assign AWS Instance Current State according to the action required to be performed.  
 # AWS Instance State Code  
 # Stopped State : 80  
 # Running State : 16  
 if [ $ACTION == "start" ];  
 then  
     INSTANCE_CURRENT_STATE=80;  
     echo "Action : Starting Instances";  
 fi;  
 if [ $ACTION == "stop" ];  
 then  
     INSTANCE_CURRENT_STATE=16;  
     echo -e "Action : Stopping Instances\n";  
 fi;  
 echo -e "Sno.\tInstance_ID\tPrivate_DNS_Name\t\t\t\tInstance_Name";  
 count=1;  
 for INSTANCE_ID in `aws ec2 describe-instances --output text --query 'Reservations[].Instances[].InstanceId' --filters "Name=tag:ADMIN_EC2_STARTSTOP,Values=Yes" "Name=instance-state-code,Values=${INSTANCE_CURRENT_STATE}" "Name=tag:Environment,Values=${ENVIRONMENT}"`;  
 do  
 ## Get Name  
 INST_NAME=$(aws ec2 describe-instances --query 'Reservations[].Instances[].[Tags[?Key==`Name`].Value]' --filters "Name=instance-id,Values=${INSTANCE_ID}" --output text);  
 ## Get Private Hostname  
 INST_PRIVATE_DNSNAME=$(aws ec2 describe-instances --query 'Reservations[*].Instances[*].[PrivateDnsName]' --filters "Name=instance-id,Values=${INSTANCE_ID}" --output=text);  
 ## Execute Operations  
 echo -e "$count\t$INSTANCE_ID\t$INST_PRIVATE_DNSNAME\t$INST_NAME";  
 count=$((count + 1));  
 if [ $ACTION == "start" ];  
 then  
     aws ec2 start-instances --instance-ids $INSTANCE_ID &>/dev/null  
 fi;  
 if [ $ACTION == "stop" ];  
 then  
     aws ec2 stop-instances --instance-ids $INSTANCE_ID &>/dev/null  
 fi;  
 done;  


The Example implementation of this code is below
#Login to the server for which you have the aws cli installed and through which you want to run this script and set the crontab for this user as below

#crontab -e

# Development Environment
# Working Window : 8:00 am to 11:55 pm [Monday ~ Saturday]
55 23 * * *  /opt/script_automation/ec2_instance_run_scheduler.sh stop Development
0 8 * * 1,2,3,4,5,6  /opt/script_automation/ec2_instance_run_scheduler.sh start Development

The working window defines the time during which our Development Environment will be available to the users to work.

Using this script you can automatically stop and start your environment and save on the AWS Billing.