Andrew Mercer

Azure virtual machines

Virtual machine scale sets

Virtual machine availability sets

Update domain

Fault domain

Create an azure virtual machine with Terraform

Creates an Azure virtual machine and installs Nginx

mkdir -p ~/terraform/azure/compute/azure_vm && \
cd ~/terraform/azure/compute/azure_vm
# main.tf

terraform {
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "~> 4.0"
    }
  }

  required_version = ">= 1.6.0"
}

provider "azurerm" {
  features {}
}

# -------------------------------
# Resource Group
# -------------------------------
resource "azurerm_resource_group" "example" {
  name     = "IntroAzureRG"
  location = "East US" # change to your region
}

# -------------------------------
# Virtual Network and Subnet
# -------------------------------
resource "azurerm_virtual_network" "example" {
  name                = "example-vnet"
  address_space       = ["10.0.0.0/16"]
  location            = azurerm_resource_group.example.location
  resource_group_name = azurerm_resource_group.example.name
}

resource "azurerm_subnet" "example" {
  name                 = "example-subnet"
  resource_group_name  = azurerm_resource_group.example.name
  virtual_network_name = azurerm_virtual_network.example.name
  address_prefixes     = ["10.0.1.0/24"]
}

# -------------------------------
# Public IP
# -------------------------------
resource "azurerm_public_ip" "example" {
  name                = "my-vm-ip"
  resource_group_name = azurerm_resource_group.example.name
  location            = azurerm_resource_group.example.location
  allocation_method   = "Static"
  sku                 = "Standard"
}

# -------------------------------
# Network Interface
# -------------------------------
resource "azurerm_network_interface" "example" {
  name                = "my-vm-nic"
  location            = azurerm_resource_group.example.location
  resource_group_name = azurerm_resource_group.example.name

  ip_configuration {
    name                          = "internal"
    subnet_id                     = azurerm_subnet.example.id
    private_ip_address_allocation = "Dynamic"
    public_ip_address_id          = azurerm_public_ip.example.id
  }
}

# -------------------------------
# Virtual Machine
# -------------------------------
resource "azurerm_linux_virtual_machine" "example" {
  name                = "my-vm"
  resource_group_name = azurerm_resource_group.example.name
  location            = azurerm_resource_group.example.location
  size                = "Standard_D2s_v5"
  admin_username      = "azureuser"
  network_interface_ids = [
    azurerm_network_interface.example.id
  ]

  admin_ssh_key {
    username   = "azureuser"
    public_key = file("~/.ssh/id_rsa.pub")
  }

  source_image_reference {
    publisher = "Canonical"
    offer     = "0001-com-ubuntu-server-jammy"
    sku       = "22_04-lts"
    version   = "latest"
  }

  os_disk {
    caching              = "ReadWrite"
    storage_account_type = "Standard_LRS"
  }

  computer_name = "my-vm"
}

# -------------------------------
# Custom Script Extension (NGINX install)
# -------------------------------
resource "azurerm_virtual_machine_extension" "nginx_setup" {
  name                 = "customScript"
  virtual_machine_id   = azurerm_linux_virtual_machine.example.id
  publisher            = "Microsoft.Azure.Extensions"
  type                 = "CustomScript"
  type_handler_version = "2.1"

  settings = jsonencode({
    fileUris = [
      "https://raw.githubusercontent.com/MicrosoftDocs/mslearn-welcome-to-azure/master/configure-nginx.sh"
    ]
  })

  protected_settings = jsonencode({
    commandToExecute = "./configure-nginx.sh"
  })
}