Using terraform to setup jMeter cluster in AWS

One of the popular choices for carrying out high-load tests is Apache JMeter. Being capable of doing everything needed for load testing (and doing it well), it is not, however, the easiest tool to set up in the cloud. To make it easier, we suggest using another tool, known as Terraform. With it, you can define your infrastructure as code and when it comes to setting it up, the automated process kicks in. Sounds easy and nice, right?

Well, in this article, we will guide you through using Terraform to set up a JMeter cluster in AWS. First, we will explain how the magic works. Then, we will share all the necessary prerequisites for setting up the whole thing. FInally, we will guide you step by step through the entire process: creating a JMeter script, generating SSH keys, creating a Terraform main.tf file, creating infrastructure, starting the load test. Now, let’s have some fun!

How it works

Terraform is an open-source infrastructure as code tool developed by HashiCorp. It allows you to define and manage your infrastructure using declarative code.

AWS - Amazon Web services, a popular cloud hosting provider with a wide range of services.

In this project, we will deal with terraform-aws-jmeter, a Terraform module that automates the setup of a jMeter cluster in AWS. This module creates one master instance and an autoscaling group with jMeter workers. Both master and workers share the same security group, which allows all ingress and egress communications inside the group. This group allows egress communications for all ports for the outside world as well, to ensure jMeter can access hosts it is supposed to test. The instances are bootstrapped with jMeter 3, and the master automatically discovers workers by searching for instances in the autoscaling group:

module "jmeter_cluster" {
  source = "github.com/r4dx/terraform-aws-jmeter"

  aws_region = "${var.aws_region}"
  slave_ssh_public_key_file = "${var.slave_ssh_public_key_file}"
  master_ssh_private_key_file = "${var.master_ssh_private_key_file}"
  master_ssh_public_key_file = "${var.master_ssh_public_key_file}"
  jmx_script_file = "${var.jmx_script_file}"
  availability_zones = "${var.availability_zones}"
  slave_instance_type = "${var.slave_instance_type}"
  slave_asg_size = "${var.slave_asg_size}"
  aws_access_key = "${var.aws_access_key}"
  aws_secret_key = "${var.aws_secret_key}"
}

It is configured using variables, which you can define in the variables.tf file:

variable "aws_access_key" {
  description = "The access key for your AWS account."
}

variable "aws_secret_key" {
  description = "The secret key for your AWS account."
}

variable "aws_region" {
  description = "The AWS region to use."
  default = "us-west-2"
}

variable "jmeter3_url" {
  description = "The URL to download Apache JMeter 3.0"
  default = "http://mirror.metrocast.net/apache//jmeter/binaries/apache-jmeter-3.0.tgz"
}


variable "slave_instance_type" {
  description = "The instance type for JMeter slave nodes."
  default = "t2.micro"
}


variable "slave_asg_size" {
  description = "The number of instances to launch for JMeter slave nodes."
  default = 1
}


variable "master_instance_type" {
  description = "The instance type for JMeter master node."
  default = "t2.micro"
}


variable "aws_amis" {
  description = "The AMIs for the specified region."
  default = {
    "us-west-2" = "ami-0e4a253fbfc47875a"
  }
}


variable "availability_zones" {
  description = "The availability zones to launch the instances in."
  default = "us-west-2a,us-west-2b,us-west-2c"
}


variable "ssh_key_name" {
  description = "The name of the SSH keypair to use."
  default = "jmeter-keypair"
}


variable "ssh_public_key_path" {
  description = "The path to the public key file."
  default = "keys/jmeter-keypair.pub"
}


variable "ssh_private_key_path" {
  description = "The path to the private key file."
  default = "keys/jmeter-keypair.pem"
}


variable "jmx_script_file" {
  description = "The path to the JMeter script file."
  default = "script.jmx"
}

Also, you can override these variables while running the terraform apply command. These variables include the AWS region, instance types and SSH keys for the master and worker nodes and also the jMeter script file that will be used for the load testing.

Prerequisites

There are a few things we need before we start setting up the infrastructure:

  • An AWS account with the necessary permissions to create EC2 instances, security groups, and other resources. You can get it, and all the info about it, at the AWS official website: http://aws.amazon.com/. Free AWS limits will work as well if you want to just try it but you'll definitely need some resources if you want to really load test something.

  • HashiCorp Terraform: you will need to install it on your local machine. To download the latest version, visit its official website: https://www.terraform.io/

Setup and testing step by step

Now that we have all the prerequisites in place, we can proceed with setting up the JMeter cluster using Terraform. The following steps will guide you through the process.

Create a JMeter script

Before you start creating the infrastructure for the JMeter cluster, you need to have a JMeter script that you want to run on the cluster. Generally this is out of the scope of the article and totally depends on your needs but usually the good way is to just use the JMeter UI. Find out how to do that here.

Generate SSH keys

To access the JMeter master and worker nodes, you will need to generate SSH keys. You can use the ssh-keygen tool to generate the keys. For example:

$ ssh-keygen -t rsa -C "loadServer" -P '' -f loadServer

This command will generate a private key file named loadServer and a public key file named loadServer.pub.

Create a Terraform configuration file

Next, you need to create a Terraform configuration file that defines the infrastructure for the JMeter cluster. Create a new file named main.tf in the project directory. Keep in mind that Terraform will be using the variables we defined earlier in the variables.tf file:

provider "aws" {
  region     = "${var.aws_region}"
  access_key = "${var.aws_access_key}"
  secret_key = "${var.aws_secret_key}"
}

module "jmeter_cluster" {
  source = "github.com/r4dx/terraform-aws-jmeter"

  aws_region                 = "${var.aws_region}"
  slave_ssh_public_key_file  = "ssh/loadServer.pub"
  master_ssh_private_key_file = "ssh/loadServer"
  master_ssh_public_key_file = "ssh/loadServer.pub"
  jmx_script_file            = "script.jmx"
}

Create infrastructure

Once you have created the Terraform configuration file, you need to run the following commands to download any required modules and apply the changes:

$ terraform get
$ terraform apply

This will create the necessary infrastructure for the JMeter cluster in your AWS account.

SSH into the JMeter master node

To start the load test, you need to SSH into the JMeter master node. SSH into the master node using its public IP address, which you can find by running this command:

$ terraform show

The command to SSH into the master node is:

$ ssh -i "loadServer" ec2-user@<MASTER_PUBLIC_IP>

Start the load test

Once you are logged into the master node, navigate to the /jmeter-master/ directory and start the load test by running the following commands:

$ cd /jmeter-master/
$ python master_start.py

Please note it takes some time to start the worker nodes. If they don't start for some reason, you can do it manually by SSHing and executing this command:

$ /apache-jmeter-3.0/bin/jmeter-server

Destroy the infrastructure

Once you are done with the load test, you can destroy the infrastructure using this command:

$ terraform destroy

This will delete all the resources that were created by Terraform.

Conclusion

In this article, we explored how to use Terraform to set up a JMeter cluster in AWS. We started by creating a JMeter script and generating SSH keys. Then, we created a Terraform main file using an example provided and configured the necessary variables.

With our infrastructure defined, we used Terraform to create our JMeter cluster by running terraform apply. Once our cluster was up and running, we logged in to the master node and started the load test. We also explored how Terraform manages resources and used terraform destroy to remove our cluster when we were done with it.

Using Terraform to create a JMeter cluster can be incredibly helpful when running large-scale load tests. By automating the process of infrastructure setup and configuration, you can easily spin up a cluster of JMeter nodes and execute tests without having to worry about the underlying infrastructure.

Overall, Terraform provides an efficient and reliable way to manage your AWS infrastructure and can help make your load testing process much more streamlined. With the steps outlined in this article, you should now have a solid foundation for creating and managing your own JMeter clusters in AWS using Terraform.