AWS Elastic Beanstalk Environment Scheduling
In this short tutorial we will learn about AWS Elastic Beanstalk Environment Scheduling using a simple Shell Script that can be used as part of a possible large automation project where for example you want to save some money on your bill by turning off and on let’s say specific environments that are not used between specific hours during weekdays or weekends for environments like Development, Staging or QA. This solution can be easily used for example being as a Cronjob on one of your management / admin servers or maybe simply as a Jenkins scheduled job, also can be used and called with automation tools like Ansible, Puppet, Chef etc., even using an AWS Lambda Function or any other tool that you can think of, it is really up to you and your specific user case. We must say that we have tested this solution on a CentOS 7 server using a simple Jenkins scheduled job and here we will try to cover pretty much everything that could help you on your automation tasks.
Table of contents
Required packages and files
Power On JSON File
Power Off JSON File
Shell Script for AWS Beanstalk Scheduling
Troubleshooting
Required packages and files
As we already said in the beginning of our tutorial we have tested this solution using a CentOS 7 server and Jenkins but you may use any other operating system or automation tools that you are comfortable with, also please make sure that you have aws
(AWS CLI) and jq
packages installed on your machine, jq
is used for parsing JSON within Shell and can be found here and aws
can be found here, both required packages have very good documentation in case you want to extend the functionality for this script.
This solution uses three files, two of these being JSON files called poweron.json
and poweroff.json
, third one is actually a Shell Script file being called check-aws-beanstalk.sh
, we will talk about their content gradually. So let’s make sure that we have these files in place first before moving to our next step:
$ mkdir -p /usr/src/check-aws-beanstalk
$ cd /usr/src/check-aws-beanstalk
$ touch power{on,off}.json check-aws-beanstalk.sh
Power On JSON File
First file that we have to edit is called poweron.json
, this file will hold all the details needed for our AWS Elastic Beanstalk Environment that we will use to power it up. So please open and edit this file with your preferred text editor and add the lines that are shown below, these can be adjusted accordingly to fit your specific case:
[
{
"Namespace": "aws:autoscaling:asg",
"OptionName": "MinSize",
"Value": "2"
},
{
"Namespace": "aws:autoscaling:asg",
"OptionName": "MaxSize",
"Value": "4"
},
{
"Namespace": "aws:autoscaling:updatepolicy:rollingupdate",
"OptionName": "RollingUpdateEnabled",
"Value": "true"
}
]
Power Off JSON File
The second file that we will edit is named poweroff.json
, this file holds the same JSON parameters as poweron.json
file except the fact that now we will fill the values with 0
meaning that our AWS Elastic Beanstalk Environment will have no (EC2) instances to run, no worries this doesn’t mean that you’re deleting the environment, this action actually means that the instances will be removed and the Environment turned off. So please open and edit the poweroff.json
file by adding the next JSON lines:
[
{
"Namespace": "aws:autoscaling:asg",
"OptionName": "MinSize",
"Value": "0"
},
{
"Namespace": "aws:autoscaling:asg",
"OptionName": "MaxSize",
"Value": "0"
},
{
"Namespace": "aws:autoscaling:updatepolicy:rollingupdate",
"OptionName": "RollingUpdateEnabled",
"Value": "false"
}
]
Shell Script for AWS Beanstalk Scheduling
Finally on our last step we have to edit check-aws-beanstalk.sh
, this file basically manages the state of our Beanstalk Environment. You can easily make proper adjustments to any of the values within this script to fit to your preferred schedule.
#!/bin/bash
PowerOnDuringWeekDaysAt="08:30"
PowerOffDuringWeekDaysAt="18:30"
CurrentTime=$(TZ=Europe/London date | sed 's/.* \([0-9]*:[0-9]*\):[0-9]*.*/\1/')
WeekDay=`date +%u` # 1 is Monday - 7 is Sunday
ListInstances=$(aws elasticbeanstalk describe-instances-health --environment-name my-aws-elastic-beanstalk-environment | jq -r '.InstanceHealthList[].InstanceId')
PowerOn=$(aws elasticbeanstalk update-environment --environment-name my-aws-elastic-beanstalk-environment --option-settings file://poweron.json)
PowerOff=$(aws elasticbeanstalk update-environment --environment-name my-aws-elastic-beanstalk-environment --option-settings file://poweroff.json)
if (($WeekDay >= 1 && $WeekDay <= 5))
then
echo "Weekdays Schedule"
echo "-----------------"
if [[ "$CurrentTime" > $PowerOnDuringWeekDaysAt ]] && [[ "$CurrentTime" < $PowerOffDuringWeekDaysAt ]]
then
echo "Schedule status: Power ON"
echo "Active between: $PowerOnDuringWeekDaysAt and $PowerOffDuringWeekDaysAt - Monday to Friday (TMZ Europe/London)"
if [[ $ListInstances = "" ]]
then
echo "No instances are currently running, Powering ON the Environment..."
$PowerOn
else
echo "Found running instances, skipping..."
fi
else
echo "Schedule status: Power OFF"
echo "Active between: $PowerOffDuringWeekDaysAt and $PowerOnDuringWeekDaysAt - Monday to Friday (TMZ Europe/London)"
if [[ $ListInstances = "" ]]
then
echo "No running instances found, skipping..."
else
echo "Found instances running, Powering OFF the Environment..."
$PowerOff
fi
fi
elif (($WeekDay >= 6 && $WeekDay <= 7))
then
echo "Weekend Schedule"
echo "----------------"
echo "Schedule status: Power OFF"
echo "Active between: Friday $PowerOffDuringWeekDaysAt and Monday $PowerOnDuringWeekDaysAt - Friday, Saturday and Sunday (TMZ Europe/London)"
if [[ $ListInstances = "" ]]
then
echo "No running instances found, skipping..."
else
echo "Found instances running, Powering OFF the Environment..."
$PowerOff
fi
fi
Troubleshooting
Sometimes you may get back error responses for this AWS Elastic Beanstalk API call like:
An error occurred (InvalidParameterValue) when calling the UpdateEnvironment operation: Environment named my-aws-elastic-beanstalk-environment is in an invalid state for this operation. Must be Ready.
A fast solution to solve this kind of errors is to simply rebuild the environment, if this does not work then you will have to clone the current environment and once the clone environment is up and running then perform a URL switch.