Deploy Multiple Windows 11 Azure VMs With Terraform

In this blog post, we will show you how to use Terraform to deploy multiple Windows 11 virtual machines (VMs) in Azure.

The following code will also join the VM to Azure AD however we have included instructions on how to not join the VMs to Azure AD.

Terraform is an open-source infrastructure as code tool that enables you to create, change, and improve your infrastructure on various cloud providers such as AWS, Azure, and Google Cloud. It provides a simple and efficient way to manage infrastructure as code, making it easier to manage and maintain your infrastructure.

Code

The following configuration will create a number of machines that are set in a variable called var.num_vms.

The following code will also join the VMs to Azure AD. If you don’t need the VMs to be joined to Azure AD, remove the following sections:

  •  identity { type   = “SystemAssigned” }
  • resource “azurerm_role_assignment” “assign-vm-role”
  • resource “azurerm_virtual_machine_extension” “aadlogin”

resource "azurerm_resource_group" "rg" {
name = var.rg_name
location = var.location  
}
resource "azurerm_virtual_network" "vnet" {
  name                = var.vnet_name
  address_space       = ["10.0.0.0/16"]
  location            = azurerm_resource_group.rg.location
  resource_group_name = azurerm_resource_group.rg.name
}
resource "azurerm_subnet" "subnet" {
  name                 = var.subnet_name
  resource_group_name  = azurerm_resource_group.rg.name
  virtual_network_name = azurerm_virtual_network.vnet.name
  address_prefixes     = ["10.0.2.0/24"]
}
resource "azurerm_network_interface" "win11nic" {
  count = var.num_vms
  name                = "${var.win11prefix}-nic-${count.index}"
  resource_group_name = azurerm_resource_group.rg.name
  location            = azurerm_resource_group.rg.location
  ip_configuration {
    name                          = "internal-nic-${count.index}"
    subnet_id                     = azurerm_subnet.subnet.id
    private_ip_address_allocation = "Dynamic"
    public_ip_address_id          = azurerm_public_ip.win11publicip[count.index].id
  }
}
resource "azurerm_network_security_group" "nsg" {
  name                = var.vm_nsg
  location            = azurerm_resource_group.rg.location
  resource_group_name = azurerm_resource_group.rg.name
    security_rule {
    name                       = "RDP"
    priority                   = 101
    direction                  = "Inbound"
    access                     = "Allow"
    protocol                   = "Tcp"
    source_port_range          = "*"
    destination_port_range     = "3389"
    source_address_prefix      = "*"
    destination_address_prefix = "*"
    
  }
}
resource "azurerm_windows_virtual_machine" "win11vm" {
  count = var.num_vms
  name                            = "${var.win11prefix}-vm-${count.index}"
  resource_group_name             = azurerm_resource_group.rg.name
  location                        = azurerm_resource_group.rg.location
  size                            = "Standard_F2s_v2" 
  admin_username                  = "vmadmin"
  admin_password                  = var.vm_password
  network_interface_ids = [
    azurerm_network_interface.win11nic.*.id[count.index],
  ]
  source_image_reference {
    publisher = "microsoftwindowsdesktop"
    offer     = "windows-11"
    sku       = "win11-22h2-pro"
    version   = "latest"
  }
  os_disk {
     name                = "${var.win11prefix}-disk-${count.index}"
    storage_account_type = "Standard_LRS"
    caching              = "ReadWrite"
  }
 identity {
        type   = "SystemAssigned"  
      
      }
}
resource "azurerm_public_ip" "win11publicip" {
  count               = var.num_vms
  name                = "${var.win11prefix}-${count.index}"
  resource_group_name = azurerm_resource_group.rg.name
  location            = azurerm_resource_group.rg.location
  allocation_method   = "Dynamic"
}
resource "azurerm_network_interface_security_group_association" "securitygroup" {
    count               = var.num_vms
    network_interface_id      = azurerm_network_interface.win11nic[count.index].id 
    network_security_group_id = azurerm_network_security_group.nsg.id
}
resource "azurerm_virtual_machine_extension" "aadlogin" {
  count      = var.num_vms
  name = "AADLoginForWindows"
  virtual_machine_id = azurerm_windows_virtual_machine.win11vm[count.index].id
  publisher = "Microsoft.Azure.ActiveDirectory"
  type = "AADLoginForWindows"
  type_handler_version = "2.0"
  
}
resource "azurerm_role_assignment" "assign-vm-role" {
  scope                =  azurerm_resource_group.rg.id
  role_definition_name = "Virtual Machine Administrator Login"
  principal_id         = var.principal_id
}

For more Azure and Terraform posts, visit the main category page.

Processing…
Success! You're on the list.


Posted

in

,

by

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.