Earlier this year, AWS introduced the ability to both scale up and down your Elastic Beanstalk EC2 instances by user defined times. Previously you could scale on user defined triggers such as CPU utilization, but with this time-based functionality you are now able to proactively scale up and plan in advance of expected traffic, as well as scale down when traffic is low or instances are not required. Here is how we have implemented this to scale down our Development environments out of office hours, saving running costs when instances are not in use. However it could be easily modified to scale up to meet traffic demands at expected peak periods on a Live environment.
To implement time-based scaling on an Elastic Beanstalk, we’re going to use .ebextensions to configure our Elastic Beanstalk. As I mentioned in a previous blog post, the AWS documentation for .ebextensions and the .config files can be found here, and goes into greater detail than I will in this post.
The content of the time-based-scaling.config file is as follows:
Resources: AutoScalingDown: DependsOn: AWSEBAutoScalingGroup Properties: AutoScalingGroupName: Ref: AWSEBAutoScalingGroup DesiredCapacity: "0" MaxSize: "0" MinSize: "0" Recurrence: "0 21 * * 1-5" Type: "AWS::AutoScaling::ScheduledAction" AutoScalingUp: DependsOn: AWSEBAutoScalingGroup Properties: AutoScalingGroupName: Ref: AWSEBAutoScalingGroup DesiredCapacity: "1" MaxSize: "1" MinSize: "1" Recurrence: "0 7 * * 1-5" Type: "AWS::AutoScaling::ScheduledAction"
In this file we are creating two time-based scaling actions;
AutoScalingDown which runs Monday to Friday at 21:00 and sets the instance capacity of the Elastic Beanstalk to zero, and
AutoScalingUp which runs Monday to Friday at 07:00 and sets the instance capacity of the Elastic Beanstalk to one. Recurrence is set by using Cron.
Once you have created the time-based-scaling.config file (and it is worth noting that any .config files need to confirm to YAML or JSON formatting standards), add it to a .ebextensions directory in the top-level directory of your source bundle. For Visual Studio, .ebextensions needs to be part of the project to be included in your archive, so make sure you have the
<Content Include=".ebextensions\time-based-scaling.config" /> entry in your project. You can additionally add conditions to this, for example you may only want a particular .config file to run against Development instances but not against Live instances, as in this case. These time-based scaling actions can be easily modified or removed as required, and after a new deployment will be ready to be actioned.
In addition, you are able to view the time-based scaling in the AWS Console under the Configuration, Scaling, Settings as follows:
You can manually add or remove time-based scaling options from here, but the advantage of using .ebextensions is that for all future Elastic Beanstalks that are created or deployed to, these settings are automatically created and applied.
By setting the time-based scaling this way, we have our Development environments running and available 07:00 to 21:00 Monday to Friday only. As an example, if you have 10 instances in your Development environment and you were to implement this scaling strategy, you would save nearly 1000 hours of instance running time per week and, depending on the sizes of these instances, make worthwhile cost savings.