Skip to content

Scalable cloud load/stress for Azure Cognitive Search. Includes a pipelined solution with Apache JMeter and Terraform to dynamically provision and destroy the required infrastructure on Azure.

License

Notifications You must be signed in to change notification settings

ignaciofls/LoadTest-AzureCognitiveSearch-Jmeter-Terraform

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

62 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

page_type languages products extensions name description urlFragment
sample
yaml
python
azure
azure-devops
azure-storage
azure-cognitive-search
services
Containerinstance
Load Testing Pipeline with JMeter, ACI and Terraform
Azure Pipeline that provisions JMeter on Azure Container Instance using Terraform for load testing scenarios with Azure Cognitive Search
jmeter-aci-terraform

Load Testing Pipeline with JMeter, ACI and Terraform

This pipeline helps to load test Azure Cognitive Search, it leverages Apache JMeter as an open source load and performance testing tool and Terraform to dynamically provision and destroy the required infrastructure on Azure. The JMeter workers and controller are hosted in Azure Container Instances (ACI) to allow VNET injection and Private Endpoint scenarios too.

Note: This is a fork from this original repo customized for Azure Cognitive Search (ACS) REST API and syntax.

Key concepts

Architecture

The flow is triggered and controlled by an Azure Pipeline on Azure DevOps. The pipeline contains a set of tasks that are organized logically in SETUP, TEST, RESULTS and TEARDOWN groups.

Task group Tasks
SETUP
  • Check if the JMeter Docker image exists
  • Validate the JMX file that contains the JMeter test definition
  • Upload JMeter JMX file to Azure Storage Account File Share
  • Provision the infrastructure with Terraform
  • TEST
  • Run JMeter test execution and wait for completion
  • RESULTS
  • Show JMeter logs
  • Get JMeter artifacts (e.g. logs, dashboard)
  • Convert JMeter tests result (JTL format) to JUnit format
  • Publish JUnit test results to Azure Pipelines
  • Publish JMeter artifacts to Azure Pipelines
  • TEARDOWN
  • Destroy all ephemeral infrastructure with Terraform
  • On the SETUP phase, JMeter agents are provisioned as Azure Container Instance (ACI) using a custom Docker image on Terraform. Through a Remote Testing approach, JMeter controller is responsible to configure all workers, consolidating all results and generating the resulting artifacts (dashboard, logs, etc).

    The infrastructure provisioned by Terraform includes:

    • Resource Group
    • Virtual Network (VNet)
    • Storage Account File Share
    • 1 JMeter controller on ACI
    • N JMeter workers on ACI

    On the RESULTS phase, a JMeter Report Dashboard and Tests Results are published in the end of each load testing execution.

    Prerequisites

    You should have the following Azure resources:

    Getting Started using the UI

    1. Create an Azure DevOps project and import this repo

    Go to Azure DevOps, create a new project, and import this repo.

    Azure DevOps new project

    Click into the Repos tab. You will get a warning saying that the repo is empty. Click on Import a repository, then for the Clone URL copy and paste this url: https://github.com/ignaciofls/LoadTest-AzureCognitiveSearch-Jmeter-Terraform

    Import this code by cloning the repo

    2. Create a service connection in Azure DevOps

    Next, create a service connection in Azure Devops as described in the DevOps documentation. This service connection will create a service principal allowing the Azure Pipelines to access the resource group.

    NOTE: Make sure to add the service connection at the subscription level (don't specify a resource group) so the service connection has access to install resource providers.

    Create a service connection

    Make a note of the Service Connection name as it will be used in next step.

    3. Creating the variable group

    Create a variable group named JMETER_TERRAFORM_SETTINGS as described in the DevOps documentation.

    Add the following variables to the variable group:

    • TF_VAR_JMETER_ACR_NAME = <your_azurecr_name>
    • TF_VAR_RESOURCE_GROUP_NAME = <your_rg_name>
    • TF_VAR_JMETER_DOCKER_IMAGE = <your_azurecr_name>.azurecr.io/jmeter
    • AZURE_SERVICE_CONNECTION_NAME = <your_service_connection_name>
    • AZURE_SUBSCRIPTION_ID = <your_subscription_id>

    When you're finished, the variable group should look similar to the image below:

    Create a variable group

    4. Creating and running the Docker pipeline

    Create a pipeline with New Pipeline (blue button, right side), chose Azure Repos Git (YAML), click on your existing repo (cloned in step 1), configure the pipeline with Existing Azure Pipelines YAML file, the path of the existing file is /pipelines/azure-pipelines.docker.yml.

    A couple of extra steps before going to the JMeter deployment pipeline:

    • Create two variables:
      • ACR_NAME = <your_azurecr_name>
      • ACR_RESOURCE_GROUP = <your_rg_name>
    • Rename the new pipeline to jmeter-docker-build (in the Pipelines tab, find the three dots inside your pipeline row and there you can rename it)

    5. Creating the JMeter pipeline

    Replicate the steps as in step #4 but with yaml file pipelines/azure-pipelines.load-test.yml and rename to jmeter-load-test. For this pipeline we will need some extra variables along with the two others:

    • API-KEY = <search_service_api_key> (and keep it secret in devops)
    • TF_VAR_JMETER_JMX_FILE = sample.jmx
    • TF_VAR_JMETER_WORKERS_COUNT = 1 (or as many as you want for scalability of the JMeter workers)
    • ACR_NAME = <your_azurecr_name>
    • ACR_RESOURCE_GROUP = <your_rg_name>

    Save the pipeline but don't run it yet. The sample.jmx needs to be updated first as described in the next step.

    6. Define the test definition inside your JMX file

    By default the test uses sample.jmx. This JMX file contains a test definition for performing HTTP requests on your_instance.search.windows.net endpoint through the 443 port.

    NOTE: You'll need to update your_instance with the name of your search service within sample.jmx. You'll also need to update your_index_name to the correct index name.

    You can simply update the it with the test definition of your preference.

    7. Run the JMeter Pipeline

    Run the pipeline as in:

    ui-run-pipeline

    Viewing Test Results

    JMeter test results are created in a JTL file (results.jtl) with CSV formatting. A Python script was created to convert JTL to JUnit format and used during the pipeline to have full integration with Azure DevOps test visualization.

    Azure DevOps with successful requests

    Error messages generated by JMeter for failed HTTP requests can also be seen on Azure DevOps.

    Azure DevOps with failed requests

    Viewing Artifacts

    Some artifacts are published after the test ends. Some of them are a static JMeter Dashboard, logs and others.

    pipeline-artifacts

    You can also download these build artifacts using az pipelines runs artifact download.

    After downloading the dashboard and unzipping it, open dashboard/index.html on your browser. Find an example under this path

    Some screenshots here: jmeter-latencies and jmeter-dashboard

    JMeter Test Configuration

    For more detail on JMeter strategy definition and config file (.jmx) please browse JMeter configuration

    Pipeline Configuration

    All Terraform parameters can be configured using the Variable Group JMETER_TERRAFORM_SETTINGS. Please read JMeter Pipeline Settings to know more details about it.

    Limitations

    • Load Test duration Please note that for Microsoft hosted agents, you can have pipelines that runs up to 1 hour (private project) or 6 hours (public project). You can have your own agents to bypass this limitation.

    • ACI on VNET regions Please note that not all regions currently support ACI and VNET integration. If you need private JMeter agents, you can deploy it in a different region and use VNET peering between them. Also note that vCPUs and memory limits change based on regions.

    Additional Documentation

    External References

    Future enhancements

    • Creation of Container Registry with IaC as part of Terraform script
    • Fully programmatic (CLI) provisioning and execution

    Contributing

    This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com.

    When you submit a pull request, a CLA bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA.

    This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact [email protected] with any additional questions or comments.

    About

    Scalable cloud load/stress for Azure Cognitive Search. Includes a pipelined solution with Apache JMeter and Terraform to dynamically provision and destroy the required infrastructure on Azure.

    Resources

    License

    Code of conduct

    Security policy

    Stars

    Watchers

    Forks

    Languages

    • HCL 53.5%
    • Python 40.5%
    • Dockerfile 6.0%