Maximizing Performance: A Step-by-Step Guide to Setting Up Azure Virtual Machines with Terraform

Prerequisites

What is Terraform?

Terraform is a tool used by developers and system administrators to create and manage infrastructure, such as virtual machines, in the cloud. It allows you to define the resources you need in a file, called a "configuration file," which Terraform can then use to automatically provision and manage those resources for you.

Set up Azure Virtual Machine with Terraform

  1. Create a terraform file

  2. Define the provider

  3. Create a resource group

  4. Define a virtual network

  5. Define a subnet

  6. Create a public key

  7. Create a public IP

  8. Define a network interface

  9. Define a network security group

  10. Define a network security rule

  11. Define a network interface security group association

  12. Create a virtual machine

  13. Build the virtual machine

  14. Conclusion

1. Create a terraform file

touch main.tf

2. Define the provider

In the main.tf file add the following code block to define the provider
You can open the file in VsCode or with any text editor such as Vim

To use Vim, use the command

vim main.tf

Now enter the following code in the main.tf file

terraform {
    required_providers {
        azurerm = {
            source = "hashicorp/azurerm"
            version = "=3.0.0"
        }
    }
}

provider "azurerm" {
    features {}
}

3. Create a resource group

Add the following code block to define a resource group where all your resources are going to be organized.
In this example, the resource group is named "myAzureDevOps"

resource "azure_resource_group" "rg" {
    name = "myAzureDevOps"
    location = "East US2"
}

4. Define a virtual network

In this example, our virtual network is named "test-network". A virtual network will help you provide security so that only authorized traffic flows in and out.

resource "azurerm_virtual_network" "azureVN" {
  name                = "test-network"
  location            = azurerm_resource_group.rg.location
  address_space       = ["10.0.0.0/16"]
  resource_group_name = azurerm_resource_group.rg.name
}

5. Define a subnet

resource "azurerm_subnet" "azureSub" {
  name                 = "test-subnet"
  resource_group_name  = azurerm_resource_group.rg.name
  virtual_network_name = azurerm_virtual_network.azureVN.name
  address_prefixes     = ["10.0.2.0/24"]
}

6. Create a public key

To create a public key, you need to create an SSH key from your terminal.
This would provide you with both public and private keys.

Create an SSH key in a different terminal

ssh-keygen -m PEM -t rsa -b 4096

Now insert the following code in addition to the already added codes to upload your public key to Azure.

resource "azurerm_ssh_public_key" "azureSSH" {
  name                = "test-public-key"
  resource_group_name = azurerm_resource_group.rg.name
  location            = azurerm_resource_group.rg.location
  public_key          = file("~/.ssh/id_rsa.pub")
}

7. Create public IP

resource "azurerm_public_ip" "azureIP" {
  name                = "test-public-ip"
  resource_group_name = azurerm_resource_group.rg.name
  location            = azurerm_resource_group.rg.location
  allocation_method   = "Dynamic"
}

8. Define network interface

resource "azurerm_network_interface" "azureNI" {
  name                = "test-interface"
  location            = azurerm_resource_group.rg.location
  resource_group_name = azurerm_resource_group.rg.name

  ip_configuration {
    name                          = "test-config"
    subnet_id                     = azurerm_subnet.azureSub.id
    private_ip_address_allocation = "Dynamic"
    public_ip_address_id          = azurerm_public_ip.azureIP.id
  }
}

9. Define network security group

resource "azurerm_network_security_group" "azureNS-group" {
  name                = "test-Security-group"
  location            = azurerm_resource_group.rg.location
  resource_group_name = azurerm_resource_group.rg.name
}

10. Define network security rule

This security rule allows inbound traffic on port 22.

resource "azurerm_network_security_rule" "azureNSG-rule" {
  name                        = "test-Security-rule"
  priority                    = 100
  direction                   = "Inbound"
  access                      = "Allow"
  protocol                    = "Tcp"
  source_port_range           = "*"
  source_address_prefix       = "*"
  destination_port_range      = "22"
  destination_address_prefix  = "*"
  resource_group_name         = azurerm_resource_group.rg.name
  network_security_group_name = azurerm_network_security_group.azureNS-group.name
}

11. Define a network interface security group association

resource "azurerm_network_interface_security_group_association" "azureNSG-asc" {
  network_interface_id      = azurerm_network_interface.azureNI.id
  network_security_group_id = azurerm_network_security_group.azureNS-group.id
}

12. Create a virtual machine

Finally, create your virtual machine with these parameters. In this example, the minimum size of a virtual machine is chosen as well as a Linux operating system.
Let's name our virtual machine test-virtual-machine.

resource "azurerm_linux_virtual_machine" "azureVM" {
  name                = "test-virtual-machine"
  resource_group_name = azurerm_resource_group.rg.name
  location            = azurerm_resource_group.rg.location
  size                = "Standard_B2s"
  admin_username      = "angelotheman"
  admin_password      = "theman_angelo@2020!"
  network_interface_ids = [
    azurerm_network_interface.azureNI.id,
  ]

  admin_ssh_key {
    username   = "angelotheman"
    public_key = azurerm_ssh_public_key.azureSSH.public_key
  }

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

  source_image_reference {
    publisher = "Canonical"
    offer     = "UbuntuServer"
    sku       = "16.04-LTS"
    version   = "latest"
  }
}

If you use Vim, make sure to save and exit your file with this command

Press the ESQ key and then

:wq

13. Build the virtual machine

You must first log in to Azure from the terminal

az login

You would be sent to a web browser to log in to your account. After successful authentication, your terminal will display your subscription information.

Create a service principal. Replace "SUBSCRIPTION_ID" with the id printed on the terminal.

az ad sp create-for-rbac --role="Contributor" --scopes="/subscriptions/<SUBSCRIPTION_ID>"

Next, set your environment variables. Replace the values in anchor braces with the values printed after the previous steps


 export ARM_CLIENT_ID="<APPID_VALUE>"
 export ARM_CLIENT_SECRET="<PASSWORD_VALUE>"
 export ARM_SUBSCRIPTION_ID="<SUBSCRIPTION_ID>"
 export ARM_TENANT_ID="<TENANT_VALUE>"

Once you have your Azure account set up from the terminal, it's time to configure the backend of your Terraform configuration.

Initialize your backend

terraform init

Format and validate the configuration

terraform fmt
terraform validate

Use terraform plan to find out what changes would be made to your infrastructure.

terraform plan

Finally, apply your configurations. Use the "--auto-approve" flag to skip the prompt from Terraform to accept or reject the proceedings.

terraform apply --auto-approve

When you are done provisioning the infrastructure you might want to clean up your resources to prevent unnecessary charges

Delete your resources

terraform delete

14. Conclusion

Using Terraform (IaC) is a simple way to provision infrastructure in our cloud services with ease. It makes it easier to track resources and make changes where necessary.

If you love this content, tap the like button, comment and follow me for more awesome content such as this.

ย