Source: https://api.octoperf.com/doc/on-premise-agent/provider-type/microsoft-azure/

# Microsoft Azure

![Microsoft Azure](https://api.octoperf.com/doc/on-premise-agent/provider-type/img/azure/microsoft-azure.png)

[Microsoft Azure](https://azure.microsoft.com/fr-fr/) is a web service that provides secure, resizable compute capacity in the cloud. It is designed to make web-scale cloud computing easier for developers.

The documentation below explains how to configure Microsoft Azure cloud provider. 

## Azure Setup

### Prerequisites

Before trying to configure Microsoft Azure, make sure you have:

- A Microsoft Azure Account with a valid subscription.

### Resource Group

![Microsoft Azure Resource Group](https://api.octoperf.com/doc/on-premise-agent/provider-type/img/azure/resource-group.png)

The resource group is a container that holds related Azure resources.

**How to create a resource group**

- Go to *Resource Groups*,
- Click on `Add`,
- In `Basics` section, select the subscription and enter `octoperf` in Resource group name,
- Select the region where the group should be located (Here in `(Europe) France Central`),
- Click on `Review + Create`.

The resource group must be named `octoperf` (all lowercase characters).

### Enterprise Application

The next step is to create Azure application credentials so OctoPerf can programmatically start and stop virtual machines on Microsoft Azure. Please see [How to Use Azure to create an application that can access resources](https://docs.microsoft.com/en-us/azure/active-directory/develop/howto-create-service-principal-portal).

Basically, you need to:

- Create an Azure Application Registration in `App Registrations` with the name you want (Example: `OctoPerf`), Application type `Web app / API` and no sign-on URL needed,
- Assign the newly created application a `Contributor` or equivalent so the application can create, start and stop virtual machines (See [How to create Service Principal](https://docs.microsoft.com/fr-fr/azure/active-directory/develop/howto-create-service-principal-portal))
- Create an Application `Client Secret` later used to authenticate from OctoPerf.

Once done, please keep a-side:

- `(Client) Application Id`,
- `Client Secret`,
- `Tenant Id`,
- And `subscription Id`.

Those information are needed to allow OctoPerf to connect to your Microsoft Azure account.

### Virtual Networks

![Microsoft Azure Virtual Network](https://api.octoperf.com/doc/on-premise-agent/provider-type/img/azure/virtual-network.png)

A virtual network for each Azure Location is required. Virtual machines spinned up by octoperf are configured with this virtual network.

**Creating a virtual network**

- Go to `Virtual Networks`,
- Click on `+ Add`,
- Name the virtual network with `octoperf-` prefix followed by the location id. Example: `octoperf-francecentral` in France Central,
- Enter `Address Space`. Example: `10.1.0.0/16`,
- Select `octoperf` resource group,
- Select the location where to create the virtual network. Example: `France Central`,
- Enter the `Address Range`. Example: `10.1.0.0/24`,
- `DDos Protection` set at your convenience. Defaults to `Basic`,
- Service Endpoints and Firewall can be left as `Disabled`.


Make sure the name of the virtual network starts with `octoperf-`. Create a virtual network per location, preferrably named `octoperf-location` (replace `location` by the actual location).

### Shared Image Gallery

![Microsoft Azure Shared Image Gallery](https://api.octoperf.com/doc/on-premise-agent/provider-type/img/azure/shared-image-gallery.png)

Our Azure integration uses [Shared Image Galleries](https://docs.microsoft.com/en-us/azure/virtual-machines/linux/shared-image-galleries) as virtual machine base image.

**Create Shared Image Gallery**

- In Azure Portal, Open `Shared Image Galleries`,
- Create a shared image gallery whose name starts with *OctoPerf* (case-insensitive).

The next step is to create a shared image definition.

**Create Image Definition**

- Select the newly created image gallery (named `OctoPerfGallery` in our case),
- Click on `Add new image definition`,
- In name, prefix it with *OctoPerf* (cas-insensitive),
- Enter all settings being asked such as `Operating System`, `VM Generation` (usually `Gen 1`), `Publisher`, `SKU` and more.

The next step is to create the first image version. The best tool to do this is [Packer](https://packer.io). 

**Create an Image using Packer**

- Here is an example packer script `azure.pkr.hcl` to build an image with Docker and octoperf images preinstalled:

```json
packer {
  required_plugins {
    azure = {
      version = ">= 2.1.3"
      source  = "github.com/hashicorp/azure"
    }
  }
}

variable "agent_version" {
  type = string
  default = "latest"
}

variable "jmeter_version" {
  type = string
  default = "latest"
}

variable "azure_client_id" {
  type = string
  sensitive = true
}

variable "azure_client_secret" {
  type = string
  sensitive = true
}

variable "azure_subscription_id" {
  type = string
  sensitive = true
}

variable "azure_tenant_id" {
  type = string
  sensitive = true
}

locals { timestamp = regex_replace(timestamp(), "[- TZ:]", "") }

source "azure-arm" "azure" {
  client_id                         = "${var.azure_client_id}"
  client_secret                     = "${var.azure_client_secret}"
  image_offer                       = "0001-com-ubuntu-server-jammy-daily"
  image_publisher                   = "Canonical"
  image_sku                         = "22_04-daily-lts"
  location                          = "westeurope"
  managed_image_name                = "octoperf-${local.timestamp}"
  managed_image_resource_group_name = "octoperf"
  managed_image_zone_resilient      = true
  os_type                           = "Linux"
  shared_image_gallery_destination {
    gallery_name        = "OctoPerfGallery"
    image_name          = "OctoPerfImage"
    image_version       = "${var.jmeter_version}"
    replication_regions = [
      "eastasia",
      "southeastasia",
      "centralus",
      "eastus",
      "eastus2",
      "westus",
      "westus2",
      "westus3",
      "northcentralus",
      "southcentralus",
      "northeurope",
      "westeurope",
      "japanwest",
      "japaneast",
      "brazilsouth",
      "australiaeast",
      "australiasoutheast",
      "southindia",
      "centralindia",
      "westindia",
      "canadacentral",
      "canadaeast",
      "uksouth",
      "ukwest",
      "westcentralus",
      "koreacentral",
      "koreasouth",
      "francecentral",
      "australiacentral",
      "uaenorth",
      "southafricanorth",
      "switzerlandnorth",
      "germanywestcentral",
      "norwayeast",
      "swedencentral",
      "qatarcentral"
    ]
    resource_group      = "octoperf"
  }
  ssh_username    = "ubuntu"
  subscription_id = "${var.azure_subscription_id}"
  tenant_id = "${var.azure_tenant_id}"
}

build {
  sources = ["source.azure-arm.azure"]

  provisioner "shell" {
    inline = [
      "sudo rm -rvf /var/lib/apt/lists/*",
      "sudo apt-get clean",
      "curl -fsSL https://get.docker.com -o get-docker.sh",
      "sudo sh get-docker.sh",
      "sudo usermod -aG docker ubuntu",
      "sudo docker pull octoperf/docker-agent:${var.agent_version}",
      "sudo docker pull octoperf/jmeter-standard:${var.jmeter_version}",
      "sudo docker pull octoperf/jmeter-webdriver:${var.jmeter_version}",
      "sudo docker pull octoperf/jmeter-playwright:${var.jmeter_version}",
      "sudo docker pull octoperf/k6:${var.jmeter_version}"
    ]
  }

  provisioner "shell" {
    execute_command = "chmod +x {{ .Path }}; {{ .Vars }} sudo -E sh '{{ .Path }}'"
    inline          = ["/usr/sbin/waagent -force -deprovision+user && export HISTSIZE=0 && sync"]
    inline_shebang  = "/bin/sh -x"
  }

  post-processor "manifest" {
    output     = "azure-manifest.json"
    strip_path = true
  }
}

```

This is the variables file `vars.json`:

```json
agent_version = "latest"
jmeter_version = "latest"

azure_client_id = "YOUR_AZURE_CLIENT_ID"
azure_client_secret = "YOUR_AZURE_CLIENT_SECRET"
azure_subscription_id = "YOUR_AZURE_SUBSCRIPTION_ID"
azure_tenant_id = "YOUR_AZURE_TENANT_ID"
```

Make sure to replace `xx.x.x` by the latest version in [release notes](https://api.octoperf.com/doc/release-notes/).

To run the script:

```bash
packer init -upgrade azure.pkr.hcl
packer build -var-file=variables.pkrvars.hcl azure.pkr.hcl
```

![Microsoft Azure Shared Image Gallery Version](https://api.octoperf.com/doc/on-premise-agent/provider-type/img/azure/shared-image-gallery-version.png)

Once the build is finished, it should have created an image with docker and OctoPerf docker images preinstalled. This image is not replicated by default. Fill `replicated_regions` to automatically replicate the image in all the specified regions.

## OctoPerf Azure Provider

### Access

![azure-access](https://api.octoperf.com/doc/on-premise-agent/provider-type/img/azure/azure-access.png){ align=left }

The final step is to [create the Microsoft Azure provider](https://api.octoperf.com/doc/on-premise-agent/providers/#create-a-new-provider) from OctoPerf's UI.

To guarantee access to Azure from your OctoPerf account the following settings are required:

- **Application (client) ID**: id of the application,
- **Client Secret**: the secret password generated when creating the Azure enterprise application,
- **Directory (tenant) ID**: tenant ID,
- **Subscription ID**: id of the subscription to use,
- **Environment**: `Azure` by default,
- **Resource Group**: `octoperf` by default.

<div style="clear:both"></div>

### SSH

![azure-ssh](https://api.octoperf.com/doc/on-premise-agent/provider-type/img/azure/azure-ssh.png)

Virtual machines created by OctoPerf can be sshed using the settings provided here:

- **SSH User**: username to use to ssh into the virtual machine instance from outside,
- **SSH Password or Public Key**: Either a password or an SSH public key.

### Locations

![Microsoft Azure Provider Regions](https://api.octoperf.com/doc/on-premise-agent/provider-type/img/azure/azure-region.png)

OctoPerf automatically detected your Azure locations based on a naming convention. 

!!! warning
    If no location is being pre-configured, make sure you followed all the steps in `Azure Setup` prior to trying to configure Azure in OctoPerf.

In every location OctoPerf expects:

- **Name**: name of the region,
- **Gallery**: name of the shared image gallery,
- **Image**: name of the image within the shared image gallery to use,
- **Version**: version of the shared image to use. if none specified, the first image available is used,
- **Network name**: a **virtual network** prefixed with `octoperf-` within the same region,
- **Network Subnet**: a subnet with the name of your choice, usually `default` (must exist within the virtual network).

!!! Info
    The search functions are detailed in [this section of the navigation page](https://api.octoperf.com/doc/navigation/#filters).

### Static IPs

![Microsoft Azure Provider Static IPs](https://api.octoperf.com/doc/on-premise-agent/provider-type/img/azure/static-ips.png)

Microsoft Azure [Public IPs](https://docs.microsoft.com/en-us/azure/virtual-network/virtual-network-public-ip-address) can be allocated through the UI. When a virtual machine is started, the public IP within the same region is automatically assigned to it.
