AWS DevOps Blog

Optimizing the cost of running AWS Elastic Beanstalk Workloads

AWS Elastic Beanstalk handles provisioning resources, maintenance, health checks, automatic scaling, and other common tasks necessary to keep your application running, which allows you to focus on your application code.

You can now run your applications on Elastic Beanstalk using Amazon Elastic Compute Cloud (Amazon EC2). Spot Instances in both single instance and load balanced environments, For more information see Spot instances support. Spot Instances let you take advantage of unused Amazon EC2 capacity in the AWS Cloud. Spot Instances are available at up to a 90% discount compared to On-Demand prices, which are also available for other deployment services like Amazon Elastic Container Service (Amazon ECS) and Amazon Elastic Kubernetes Service (Amazon EKS). You can use Spot Instances for various stateless, fault-tolerant, or flexible applications, and other test and development workloads.

Customers often ask how to save costs when running their Elastic Beanstalk applications, especially when it comes to test or stage workloads, which don’t need to run all the time. This post walks you through different automation techniques that can reduce your AWS monthly bill significantly.

Converting the environment type

If you have multiple load balanced test environments and want to keep them running after work hours with the lowest possible cost, you can convert the environment type from load balanced to single instance after work hours and back to load balanced in the morning using Amazon Command Line Interface (AWS CLI) commands. For more information see Elastic Beanstalk configuration options.

To convert from load balanced to single instance, enter the following code:

$ aws elasticbeanstalk update-environment --application-name YOUR-APP_NAME --environment-name ENV_NAME --option-settings Namespace=aws:elasticbeanstalk:environment,OptionName=EnvironmentType,Value=SingleInstance

To convert from single instance to load balanced, enter the following code:

$ aws elasticbeanstalk update-environment --application-name YOUR-APP_NAME --environment-name ENV_NAME --option-settings Namespace=aws:elasticbeanstalk:environment,OptionName=EnvironmentType,Value=LoadBalanced

You can then configure cron jobs for these commands at the required times:

# ┌───────────── minute (0 - 59)
# │ ┌───────────── hour (0 - 23)
# │ │ ┌───────────── day of the month (1 - 31)
# │ │ │ ┌───────────── month (1 - 12)
# │ │ │ │ ┌───────────── day of the week (0 - 6) (Sunday to Saturday; 7 is also Sunday on some systems)
# │ │ │ │ │                                  
# * * * * * command to execute

Setting the number of instances

When you have many resources in Elastic Beanstalk environments and want to the optimize the cost during low-traffic times or after work hours while keeping the environment running, a good approach is to set the number of instances to (0 or 1) or any minimal number of instances for all test environments. See the following code:

$ aws elasticbeanstalk update-environment --environment-name ENV-NAME --option-settings Namespace=aws:autoscaling:asg,OptionName=MinSize,Value=0

The preceding code sets the number of instances to 0 while the environment is still running. You can automate this approach for a number of Elastic Beanstalk environments using the following sample bash script:

#!/bin/bash
if [ -z "$1" ] ; then
     echo "$0: <instances to set>"
     exit 1
else
    INSTANCES=$1
fi
 
for environment in environment-1  environment-2 ; do            //please provide here environment names
    aws elasticbeanstalk update-environment --environment-name $environment --option-settings Namespace=aws:autoscaling:asg,OptionName=MinSize,Value=$INSTANCES
done

You can configure a cron job to run this script on a daily basis as per the following example code:

# To set number of instances to 0 (for example at 5:00 PM every day)
$ 0 17 * * * sh test.sh 0    
# To set number of instances to 1 (for example at 8 am)
$ 0 8 * * *  sh test.sh 1 

Stopping your testing environments

When you want to stop all your testing environments overnight, you can terminate Elastic Beanstalk environments after work times and restore them again in the morning. See the following code:

# To terminate environment using AWS CLI (for example at 5:00 PM every day)
$ 0 17 * * * aws elasticbeanstalk terminate-environment --environment-name my-stage-env 
# To restore environment (for example at 8 am)
$ 0 8 * * * eb restore environment-id

For more information, see Terminate an Elastic Beanstalk environment and Rebuilding a terminated environment.

When you terminate Elastic Beanstalk environments, you lose any Amazon Relational Database Service (Amazon RDS) instances that was created previously as a part of the environment. To avoid this, decouple Amazon RDS from your environments. For instructions see, How do I decouple an Amazon RDS instance from an Elastic Beanstalk environment.

Conclusion

In this post, we discussed how different automation techniques can optimize the cost of running Elastic Beanstalk applications, which can result in a significant cost savings. Please feel free to use any approach that suits you or a combination of all of them, depending on your use case.

We appreciate your feedback.