Terraform On Azure - Creating A Azure Virtual Machine

Introduction

Azure Virtual Machine is a popular Infrastructure-as-a-service offering and you can use it to host on-premises applications with just a lift and shift approach. This is one of the frequently used Azure services. In this article, we will learn how to spin up Azure Virtual Machine using Terraform.

In the previous articles, we learned the basics of Terraform and we created an Azure WebApp using Terraform. The following are the links to the previous articles.

Create Azure Virtual Machine using Terraform 

Let us create a simple Windows-based Azure Virtual Machine. The following are the resources that we must create before spinning out a Virtual Machine. 

  • Resource Group
  • Virtual Network with Subnet
  • Network Interface card

Let start with creating the prerequisites resources and then we can create the Azure Virtual Machine.

Log in to the Azure portal at https://portal.azure.com. Let us use Azure Cloud Shell to create resources using Terraform. Azure Cloud Shell has Terraform installed and you need not do any installation or configuration to work with Terraform. 

Terraform On Azure - Creating A Azure Virtual Machine

Once the Azure Cloud Shell opens up, select Bash. Let us start creating scripts to create an Azure Virtual Machine. We can use a nano editor to create the Infrastructure as Code script for the Virtual Machine using Terraform. 

Terraform On Azure - Creating A Azure Virtual Machine

Execute the following command to open a nano editor and create a file named myterraformscript.tf.

nano myterraformscript.tf

Add the following code to the nano editor. This would create a Resource Group. Replace {ResourceGroup} with the name of your Resource Group that you are planning to create.

terraform {  
  required_providers {  
    azurerm = {  
      source = "hashicorp/azurerm"  
    }  
  }  
}  
provider "azurerm" {  
  features {}  
}  
resource "azurerm_resource_group" "{ResourceGroup}" {  
  name = "{ResourceGroup}"  
  location = "eastus"  
} 

Add the following code in nano editor to create a Virtual Network and a Subnet. Replace {ResourceGroup} with the name of your Resource Group, {VirtualNetwork} with the name of your Virtual Network and {Subnet} with the name of your Subnet. 

resource "azurerm_virtual_network" "{VirtualNetwork}" {
  name                = "{VirtualNetwork}"
  address_space       = ["10.1.0.0/24"]
  location            = azurerm_resource_group.{ResourceGroup}.location
  resource_group_name = azurerm_resource_group.{ResourceGroup}.name
}

resource "azurerm_subnet" "{Subnet}" {
  name                 = "{Subnet}"
  resource_group_name  = azurerm_resource_group.{ResourceGroup}.name
  virtual_network_name = azurerm_virtual_network.{VirtualNetwork}.name
  address_prefixes     = ["10.1.0.0/26"]
}

Add the following code to create a Network Interface Card. Replace {ResourceGroup} with the name of your Resource Group, {NIC} with the name of your Network Interface Card, {Subnet} with the name of the Subnet, and {IP} with the name of your IP resource associated with the Network Interface Card.

resource "azurerm_network_interface" "{NIC}" {
  name                = "{NIC}"
  location            = azurerm_resource_group.{ResourceGroup}.location
  resource_group_name = azurerm_resource_group.{ResourceGroup}.name

  ip_configuration {
    name                          = "{IP}"
    subnet_id                     = azurerm_subnet.{Subnet}.id
    private_ip_address_allocation = "Dynamic"
  }
}

Add the following code to create a Virtual Machine. Replace {ResourceGroup} with the name of your Resource Group, {NIC} with the name of your Network Interface Card. You need to provide the VM SKU, Operating System, and credentials in the script. 

resource "azurerm_windows_virtual_machine" "{VirtualMachine}" {
  name                = "{VirtualMachine}"
  resource_group_name = azurerm_resource_group.{ResourceGroup}.name
  location            = azurerm_resource_group.{ResourceGroup}.location
  size                = "Standard_F2"
  admin_username      = "[Provide a Username]"
  admin_password      = "[Provide your Password]"
  network_interface_ids = [
    azurerm_network_interface.{NIC}.id,
  ]

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

  source_image_reference {
    publisher = "MicrosoftWindowsServer"
    offer     = "WindowsServer"
    sku       = "2016-Datacenter"
    version   = "latest"
  }
}

The following is the script file that you created. You can refer to the attached script file and try out the sample.

terraform {  
  required_providers {  
    azurerm = {  
      source = "hashicorp/azurerm"  
    }  
  }  
}  
provider "azurerm" {  
  features {}  
}  
resource "azurerm_resource_group" "{ResourceGroup}" {  
  name = "{ResourceGroup}"  
  location = "eastus"  
} 
resource "azurerm_virtual_network" "{VirtualNetwork}" {
  name                = "{VirtualNetwork}"
  address_space       = ["10.1.0.0/24"]
  location            = azurerm_resource_group.{ResourceGroup}.location
  resource_group_name = azurerm_resource_group.{ResourceGroup}.name
}

resource "azurerm_subnet" "{Subnet}" {
  name                 = "{Subnet}"
  resource_group_name  = azurerm_resource_group.{ResourceGroup}.name
  virtual_network_name = azurerm_virtual_network.{VirtualNewtwork}.name
  address_prefixes     = ["10.1.0.0/26"]
}

resource "azurerm_network_interface" "{NIC}" {
  name                = "{NIC}"
  location            = azurerm_resource_group.{ResourceGroup}.location
  resource_group_name = azurerm_resource_group.{ResourceGroup}.name

  ip_configuration {
    name                          = "{IP}"
    subnet_id                     = azurerm_subnet.{Subnet}.id
    private_ip_address_allocation = "Dynamic"
  }
}

resource "azurerm_windows_virtual_machine" "{VirtualMachine}" {
  name                = "{VirtualMachine}"
  resource_group_name = azurerm_resource_group.{ResourceGroup}.name
  location            = azurerm_resource_group.{ResourceGroup}.location
  size                = "Standard_F2"
  admin_username      = "Provide username"
  admin_password      = "Provide Password"
  network_interface_ids = [
    azurerm_network_interface.{NIC}.id,
  ]

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

  source_image_reference {
    publisher = "MicrosoftWindowsServer"
    offer     = "WindowsServer"
    sku       = "2016-Datacenter"
    version   = "latest"
  }
}

Run the following command to initiate Terraform. This would fetch all dependencies needed to execute the Terraform script.

terraform init

Now let us create an execution plan for Terraform. Let us provide the name of the execution plan in the out parameter.

terraform plan -out myvm.tfplan

Execute the execution plan using the following command. The Virtual Machine gets created.

terraform apply "myvm.tfplan"

Conclusion

In this article, we learned how to create an Azure Virtual Machine. In the next article, we will learn how to create a Storage Account using Terraform scripts.