Deploy A Simple Windows VM (101-vm-simple-windows) Using Terraform


This terraform configuration will deploy a simple Windows VM on Azure cloud, and this is a conversion of 101-vm-simple-windows  from azure_quickstart_templates.  This configuration consists of two .tf files (variables.tf and main.tf) and deploy a single vm with the following resources…

Visualized in ARMVIZ

Deployed resources

Configuration

  • variables.tf

Variables are separated from the main configuration, and this configuration accepts the variable below…

provider "azurerm" {
    version = "=1.36.0"
}

variable "resourceGroupName" {
    type        = string
    description = "Resource Group for this deployment."
}

variable "location" {
    type        = string
    description = "Location for all resources"
}

variable "adminUsername" {
    type        = string
    description = "Username for the Virtual Machine."
}

variable "adminPassword" {
    type        = string
    description = "Password for the Virtual Machine."
}

variable "dnsLabelPrefix" {
    type        = string
    description = "Unique DNS Name for the Public IP used to access the Virtual Machine."
}

variable "windowsOSVersion" {
    type        = list
    default     = ["2016-Datacenter","2008-R2-SP1","2012-Datacenter","2012-R2-Datacenter","2016-Nano-Server","2016-Datacenter-with-Containers","2019-Datacenter"]
    description = "The Windows version for the VM. This will pick a fully patched image of this given Windows version."
}

variable "vmSize" {
    type    = string
    default = "Standard_A2_v2"
    description = "Size of the virtual machine."
}
  • main.tf

This file contains the actual configuration to create a simple Windows VM…

# Declaring the local variables
locals  {
    storageAccountName          = lower(join("", ["sawinvm", random_string.asaname-01.result]))
    nicName                     = "myVMNic"
    addressPrefix               = "10.0.0.0/16"
    subnetName                  = "Subnet"
    subnetPrefix                = "10.0.0.0/24"
    publicIPAddressName         = "myPublicIP"
    vmName                      = "SimpleWinVM"
    virtualNetworkName          = "MyVNET"
    networkSecurityGroupName    = "default-NSG"
    osDiskName                  = join("",[local.vmName, "_OsDisk_1_", lower(random_string.avmosd-01.result)])
}

# Generating the random string to create a unique storage account
resource "random_string" "asaname-01" {
    length  = 16
    special = "false"
}

# Generating the random string to create a unique os disk 
resource "random_string" "avmosd-01" {
    length  = 32
    special = "false"
}

# Resource Group
resource "azurerm_resource_group" "arg-01" {
    name        = var.resourceGroupName
    location    = var.location
}

# Storage Account
resource "azurerm_storage_account" "asa-01" {
    name                        = local.storageAccountName
    resource_group_name         = azurerm_resource_group.arg-01.name
    location                    = azurerm_resource_group.arg-01.location
    account_replication_type    = "LRS"
    account_tier                = "Standard"
}

# Public IP
resource "azurerm_public_ip" "apip-01" {
    name                = local.publicIPAddressName
    resource_group_name = azurerm_resource_group.arg-01.name
    location            = azurerm_resource_group.arg-01.location
    allocation_method   = "Dynamic"
    domain_name_label   = var.dnsLabelPrefix
}

# Network Security Group with allow RDP rule 
resource "azurerm_network_security_group" "ansg-01" {
    name                = local.networkSecurityGroupName
    resource_group_name = azurerm_resource_group.arg-01.name
    location            = azurerm_resource_group.arg-01.location
    security_rule {
        name                        = "default-allow-3389"
        priority                    = 1000
        access                      = "Allow"
        direction                   = "Inbound"
        destination_port_range      = 3389
        protocol                    = "Tcp"
        source_port_range           = "*"
        source_address_prefix       = "*"
        destination_address_prefix  = "*"
    }
}

# Virtual Network
resource "azurerm_virtual_network" "avn-01" {
    name                = local.virtualNetworkName
    resource_group_name = azurerm_resource_group.arg-01.name
    location            = azurerm_resource_group.arg-01.location
    address_space       = [local.addressPrefix]
}

# Subnet
resource "azurerm_subnet" "as-01" {
    name                  = local.subnetName
    resource_group_name   = azurerm_resource_group.arg-01.name
    virtual_network_name  = azurerm_virtual_network.avn-01.name
    address_prefix        = local.subnetPrefix
}

# Associate the subnet with NSG
resource "azurerm_subnet_network_security_group_association" "asnsga-01" {
    subnet_id                   = azurerm_subnet.as-01.id
    network_security_group_id   = azurerm_network_security_group.ansg-01.id
}

# Network Interface Card
resource "azurerm_network_interface" "anic-01" {
    name                = local.nicName
    resource_group_name = azurerm_resource_group.arg-01.name
    location            = azurerm_resource_group.arg-01.location
    ip_configuration {
        name                            = "ipconfig1"
        private_ip_address_allocation   = "Dynamic"
        public_ip_address_id            = azurerm_public_ip.apip-01.id
        subnet_id                       = azurerm_subnet.as-01.id
    }
}

# Virtual Machine
resource "azurerm_virtual_machine" "avm-01" {
    name                    = local.vmName
    resource_group_name     = azurerm_resource_group.arg-01.name
    location                = azurerm_resource_group.arg-01.location
    vm_size                 = var.vmSize
    network_interface_ids   = [azurerm_network_interface.anic-01.id]
    os_profile {
        computer_name   = local.vmName
        admin_username  = var.adminUsername
        admin_password  = var.adminPassword
    }
    storage_image_reference {
        publisher   = "MicrosoftWindowsServer"
        offer       = "WindowsServer"
        sku         = var.windowsOSVersion[0]
        version     = "latest"
    }
    storage_os_disk {
        name            = local.osDiskName
        create_option   = "FromImage"
    }
    storage_data_disk {
        name            = "Data"
        disk_size_gb    = 1023
        lun             = 0
        create_option   = "Empty"
    }
    os_profile_windows_config {
        provision_vm_agent  = true
    }
    boot_diagnostics {
        enabled     = true
        storage_uri = azurerm_storage_account.asa-01.primary_blob_endpoint
    }
}

# Print virtual machine dns name
output "hostname" {
    value   = azurerm_public_ip.apip-01.fqdn
}

Deploy the configuration

Authentication

Please use AzureCli to authenticate to your Azure cloud environment, terraform can use the same session to deploy the resources. Check here  for alternate methods of authentication.

Initialization

First time you need to initialize the configuration directory, where it will download the necessary plugins to deploy the current configuration, to initialize you need to run the command below…

terraform init
Plan

Terraform will check for the syntax errors and generates the execution plan, you can also save this plan for your future deployments

terraform plan
Apply

To apply the configuration run the command below…

terraform apply

 iac  
Share it on     |   |   |   | 
  Prev:  

List Of Available Azure VM Image Skus Using New Azure PowerShell Module Az

  :Next  

Create And Assign A Public IP To An Azure Virtual Machine

comments powered by Disqus