feat(devops): Add example for spinning up performance testing VMs on Azure (#4647)

Sets up boilerplate for Azure performance testing infra.

They have some really interesting high performance VMs that would be
fitting for our use cases, including [ones with RDMA-enabled Infiniband
networking
cards](https://learn.microsoft.com/en-us/azure/virtual-machines/extensions/enable-infiniband)
if we really want to go wild.
This commit is contained in:
Jamil
2024-05-17 09:39:21 -07:00
committed by GitHub
parent b1dde546ab
commit bf1abcfbfa
4 changed files with 206 additions and 0 deletions

View File

@@ -0,0 +1,2 @@
# This dir is simply an example; don't commit the lockfile
/.terraform.lock.hcl

View File

@@ -0,0 +1,59 @@
# Performance Terraform environment
This directory contains terraform examples for spinning up VMs on Azure to be
used for performance testing.
This is primarily meant to be used internal by the Firezone Team at this time,
but anyone can use the scripts here by changing the variables in a local
`terraform.tfvars` as needed.
## Get started
1. [Install](https://developer.hashicorp.com/terraform/tutorials/aws-get-started/install-cli)
Terraform if you haven't already.
1. [Install](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli) the
Azure CLI if you haven't already.
1. Clone this repository, and `cd` to this directory.
1. Run `terraform init` to initialize the directory.
1. Login to Azure using the Azure CLI with `az login`.
1. Find the subscription ID you want to use with `az account subscription list`.
If unsure, contact your Azure admin to avoid incurring billing charges under
the wrong billing subscription.
1. Generate a keypair to use for your own admin SSH access (**must** be RSA):
```shell
ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa.azure
```
1. Obtain `terraform.tfvars` using one of the following methods:
1. Your team's shared credentials vault (e.g. 1password)
1. Your Azure admin
1. Or, generate it by following the instructions at
https://developer.hashicorp.com/terraform/tutorials/azure-get-started/azure-build
and populating a `terraform.tfvars` file in this directory:
```hcl
# Azure billing subscription ID
subscription_id = "SUBSCRIPTION-ID-FROM-PREVIOUS-STEP"
# Obtain these variables by following the guide above
arm_client_id = "AZURE-SERVICE-PRINCIPAL-CLIENT-ID"
arm_client_secret = "AZURE-SERVICE-PRINCIPAL-CLIENT-SECRET"
arm_tenant_id = "AZURE-SERVICE-PRINCIPAL-TENANT-ID"
# All VMs need a public RSA SSH key specified for the admin user. Insert yours below.
admin_ssh_public_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC7..."
# Set your own naming prefix to avoid clobbering others' resources
naming_prefix = "CHANGEME"
```
1. Run `terraform apply` to create the resources.
1. Done! You can now SSH into your VM like so:
```shell
# Login using the name of resources used in Terraform config above
az ssh vm \
--resource-group CHANGEME-rg-westus2 \
--vm-name CHANGEME-vm-westus2 \
--private-key-file ~/.ssh/id_rsa.azure \
--local-user adminuser
```

View File

@@ -0,0 +1,116 @@
locals {
# Find this with `az account subscription list`
arm_subscription_id = var.subscription_id
# Generate these by following
# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/guides/service_principal_client_secret?ajs_aid=fdab1b75-b67a-4e43-8a41-7cb014d5c881&product_intent=terraform#creating-a-service-principal-using-the-azure-cli
#
# and then saving to terraform.tfvars in this directory:
#
# arm_client_id = "..."
# arm_client_secret = "..."
# arm_tenant_id = "..."
arm_client_id = var.arm_client_id
arm_client_secret = var.arm_client_secret
arm_tenant_id = var.arm_tenant_id
}
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~> 3.0.2"
}
}
required_version = ">= 1.1.0"
}
provider "azurerm" {
features {}
}
# US-west resource group
resource "azurerm_resource_group" "rg-westus2" {
name = "${var.naming_prefix}-rg-westus2"
location = "westus2"
}
# US-west virtual network
resource "azurerm_virtual_network" "vnet-westus2" {
name = "${var.naming_prefix}-vnet-westus2"
resource_group_name = azurerm_resource_group.rg-westus2.name
location = azurerm_resource_group.rg-westus2.location
address_space = ["10.0.0.0/16"]
}
# US-west subnet
resource "azurerm_subnet" "subnet-westus2" {
name = "${var.naming_prefix}-subnet-westus2"
resource_group_name = azurerm_resource_group.rg-westus2.name
virtual_network_name = azurerm_virtual_network.vnet-westus2.name
address_prefixes = ["10.0.0.0/24"]
}
# NIC for US-west VM
resource "azurerm_network_interface" "nic-westus2" {
name = "${var.naming_prefix}-nic-westus2"
location = azurerm_resource_group.rg-westus2.location
resource_group_name = azurerm_resource_group.rg-westus2.name
# Enable accelerated networking, can only be enabled on one NIC per VM
enable_accelerated_networking = true
ip_configuration {
name = "${var.naming_prefix}-ipconfig-westus2"
subnet_id = azurerm_subnet.subnet-westus2.id
private_ip_address_allocation = "Dynamic"
public_ip_address_id = azurerm_public_ip.publicip-westus2.id
}
}
# Public IP for US-west VM
resource "azurerm_public_ip" "publicip-westus2" {
name = "${var.naming_prefix}-publicip-westus2"
location = azurerm_resource_group.rg-westus2.location
resource_group_name = azurerm_resource_group.rg-westus2.name
allocation_method = "Dynamic"
}
# US-west VM
resource "azurerm_linux_virtual_machine" "vm-westus2" {
name = "${var.naming_prefix}-vm-westus2"
resource_group_name = azurerm_resource_group.rg-westus2.name
location = azurerm_resource_group.rg-westus2.location
# 16 vCPUs, 56 GB RAM, Premium SSD
size = "Standard_DS5_v2"
network_interface_ids = [
azurerm_network_interface.nic-westus2.id
]
# Username of the admin user
admin_username = "adminuser"
admin_ssh_key {
username = "adminuser"
public_key = var.admin_ssh_pubkey
}
# Allow others access to the VM
identity {
type = "SystemAssigned"
}
os_disk {
caching = "ReadWrite"
storage_account_type = "Standard_LRS"
}
source_image_reference {
publisher = "Canonical"
offer = "0001-com-ubuntu-server-jammy"
sku = "22_04-lts"
version = "latest"
}
}

View File

@@ -0,0 +1,29 @@
variable "subscription_id" {
description = "The Azure billing subscription to use"
type = string
}
variable "arm_client_id" {
description = "The Azure service principal client id"
type = string
}
variable "arm_client_secret" {
description = "The Azure service principal client secret"
type = string
}
variable "arm_tenant_id" {
description = "The Azure service principal tenant id"
type = string
}
variable "admin_ssh_pubkey" {
description = "The SSH public key to use for the admin user"
type = string
}
variable "naming_prefix" {
description = "The prefix to use for all resources"
type = string
}