AWS DevOps & Developer Productivity Blog

Using Locust on AWS Elastic Beanstalk for Distributed Load Generation and Testing

AWS Elastic Beanstalk customers frequently ask how to load test their web applications running on Elastic Beanstalk. Load testing, which allows you to demonstrate and understand how the application and the underlying resources function under real-world demands, is an important part of the application development cycle. Creating tests that simulate real-world scenarios is essential. Locust, an open source load testing tool, makes this easy by allowing you to write tests as a Python script.

In this post, I explain how to run Locust on Elastic Beanstalk using the Elastic Beanstalk Command Line Interface (EB CLI) to load test applications.

Locust Dashboard Showing 10,000 Concurrent Users with More Than 100,000 Requests per Second

Deploy Locust to Elastic Beanstalk

Begin by deploying Locust:

  1. If you don’t already have the EB CLI installed, install it.
  2. In the AWS Identity and Access Management (IAM) console, create an IAM instance profile named aws-elasticbeanstalk-locust-role. For information on how to create an IAM instance profile, see Create an IAM Instance Profile for Your Amazon EC2 Instances.
  3. Add the following policy to your instance profile.

    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Sid": "DynamoDBPermissions",
                "Effect": "Allow",
                "Action": [
                    "dynamodb:GetItem",
                    "dynamodb:UpdateItem"
                ],
                "Resource": [
                    "arn:aws:dynamodb:*:*:table/*-stack-MasterIPTable*"
                ]
            },
            {
                "Sid": "ElasticBeanstalkPermissions",
                "Effect": "Allow",
                "Action": [
                    "autoscaling:DescribeAutoScalingGroups",
                    "cloudformation:ListStackResources",
                    "elasticbeanstalk:DescribeEnvironmentResources"
                ],
                "Resource": [
                    "*"
                ]
            }
        ]
    }          
  4. Clone the repository that contains the sample source code by running git clone https://www.github.com/awslabs/eb-locustio-sample.
  5. Navigate to the folder where you cloned the sample code. All EB CLI commands that follow must be run in this folder.
  6. Initialize the folder for use with the EB CLI by running eb init -r <region> -p “Java 8”. Replace <region> with a region identifier, such as us-west-2 (for a full list of region identifiers, see Regions and Endpoints). Or start interactive mode by running eb init then follow the steps below:

    1. Pick a region of your choice.
    2. Choose [ Create New Application ].
    3. Type a name for the application.
    4. When you are asked, “It appears you are using Python. Is this correct?” choose no.
    5. For platform, choose Java.
    6. For the platform version, choose Java 8.
    7. When you are asked, “Do you want to set up SSH for your instances?” choose no.
      Note: If you choose to enable SSH and do not already have an SSH key stored on AWS, the command ssh-keygen must be available on the path as it is used by the EB CLI to generate the SSH key to be used.
  7. Create your load generation environment by running eb create -i c3.large –scale 1 –envvars TARGET_URL=<test URL> –instance_profile aws-elasticbeanstalk-locust-role. Replace <test URL> with the URL of the web app that you want to test.
  8. Type a name for the environment.
  9. Type the CNAME prefix that you want to use for this environment.
  10. After the environment’s been created, run eb open to open the Locust dashboard and start your tests.

Modify the Test Definition

Locust provides a python script based framework for writing tests. To learn more about writing tests using Locust, see Writing a locustfile. The sample code we cloned previously includes a sample test definition that tests the root of the provided test URL every 45-50 milliseconds. Let’s modify the sample test file to increase the wait time between tests to 90-100 milliseconds. To modify the test definition:

  1. Navigate to the folder where you cloned the sample code.
  2. Edit the locustfile.py file and set the min_wait variable to 90 and max_wait variable to 100.
  3. Save and commit the changes by running git commit -am “Increase wait time”
  4. Deploy your changes to the environment by running eb deploy.
  5. After the environment’s been updated, run eb open to open the Locust dashboard and start your tests.

Scale Out the Locust Environment Beyond a Single EC2 Instance

To scale out the environment to more than one EC2 instance:

  1. Navigate to the folder where you cloned the sample code.
  2. Open the configuration file in the default editor by running eb config.
  3. Under the aws:elasticbeanstalk:command namespace, set the BatchSize to 100.
  4. Save the configuration file, and exit the editor. This starts the environment update.
  5. After the update completes, run eb scale <number of instances>. Replace <number of instances> with the number of EC2 instances that you want the environment to scale out to.
  6. After the additional instances have been added, run eb deploy. Since Locust requires a single master, this step ensures that a single instance is selected as master after the environment has scaled out.
  7. To open the Locust dashboard and start your tests, run eb open.

Clean Up

When you are done with your tests, run eb terminate –all so that you don’t incur charges for unused AWS resources.

Conclusion

In this post, we walked through how to quickly get started with running Locust on Elastic Beanstalk for load tests. Let us know in the comments how this works for your scenarios, or reach out to us through the AWS forums if you have any technical questions.