Create an Azure VM with Terraform: A Step-by-Step Guide.

Introduction

Infrastructure as Code (IaC) is essential for managing cloud infrastructure efficiently. Terraform, an open-source IaC tool, allows you to define, deploy, and manage Azure resources in a repeatable and automated way.

In this guide, we’ll walk through deploying an Azure Virtual Machine (VM) using Terraform, covering:

Defining a resource group
Creating a virtual network and subnet
Configuring a public IP and network interface
Deploying a Windows Virtual Machine
Running Terraform commands to provision infrastructure

By the end, you’ll have a fully functional Azure VM managed via Terraform, making deployments more efficient and scalable. 🚀


Prerequisites

Before getting started, ensure you have:
An active Azure subscription
Azure CLI installed (az --version)
Terraform installed (terraform -v)
Editor (VS Code recommended with Terraform extension)


Step 1: Initialize the Terraform Project

Create a new directory for your Terraform project and navigate into it:

1mkdir terraform-azure-vm && cd terraform-azure-vm

Create the Terraform configuration file:

1touch main.tf

Open main.tf in your editor to begin defining your infrastructure.


Step 2: Configure the Azure Provider

At the top of main.tf, define the Azure provider:

1provider "azurerm" {
2  features {}
3}

This tells Terraform to use the Azure Resource Manager (AzureRM) provider for managing Azure resources.


Step 3: Define the Resource Group

A Resource Group is required to organize and manage related Azure resources. Define it in main.tf:

1resource "azurerm_resource_group" "rg" {
2  name     = "terraform-rg"
3  location = "northeurope"
4  
5  tags = {
6    environment = "demo"
7    owner       = "terraform-user"
8  }
9}

Step 4: Create a Virtual Network and Subnet

Define a Virtual Network (VNet) and Subnet for networking within the Resource Group:

 1resource "azurerm_virtual_network" "vnet" {
 2  name                = "terraform-vnet"
 3  location            = azurerm_resource_group.rg.location
 4  resource_group_name = azurerm_resource_group.rg.name
 5  address_space       = ["10.0.0.0/16"]
 6}
 7
 8resource "azurerm_subnet" "subnet" {
 9  name                 = "terraform-subnet"
10  resource_group_name  = azurerm_resource_group.rg.name
11  virtual_network_name = azurerm_virtual_network.vnet.name
12  address_prefixes     = ["10.0.1.0/24"]
13}

Step 5: Configure a Public IP Address

To allow external access, create a Public IP address:

1resource "azurerm_public_ip" "public_ip" {
2  name                = "terraform-public-ip"
3  location            = azurerm_resource_group.rg.location
4  resource_group_name = azurerm_resource_group.rg.name
5  allocation_method   = "Static"
6  sku                 = "Standard"
7}

Step 6: Define a Network Interface (NIC)

The VM needs a Network Interface (NIC) to connect to the Subnet and Public IP:

 1resource "azurerm_network_interface" "nic" {
 2  name                = "terraform-nic"
 3  location            = azurerm_resource_group.rg.location
 4  resource_group_name = azurerm_resource_group.rg.name
 5
 6  ip_configuration {
 7    name                          = "terraform-nic-config"
 8    subnet_id                     = azurerm_subnet.subnet.id
 9    private_ip_address_allocation = "Dynamic"
10    public_ip_address_id          = azurerm_public_ip.public_ip.id
11  }
12}

Step 7: Define the Virtual Machine

Before defining the VM, create variables for secure credential handling:

 1variable "admin_username" {
 2  type        = string
 3  description = "The administrator username for the VM"
 4  default     = "azureadmin"
 5}
 6
 7variable "admin_password" {
 8  type        = string
 9  description = "The administrator password for the VM"
10  sensitive   = true
11}

Now, define the Windows Virtual Machine:

 1resource "azurerm_windows_virtual_machine" "vm" {
 2  name                  = "terraform-vm"
 3  location              = azurerm_resource_group.rg.location
 4  resource_group_name   = azurerm_resource_group.rg.name
 5  network_interface_ids = [azurerm_network_interface.nic.id]
 6  size                  = "Standard_B2s"
 7  admin_username        = var.admin_username
 8  admin_password        = var.admin_password
 9
10  source_image_reference {
11    publisher = "MicrosoftWindowsServer"
12    offer     = "WindowsServer"
13    sku       = "2019-Datacenter"
14    version   = "latest"
15  }
16
17  os_disk {
18    caching              = "ReadWrite"
19    storage_account_type = "Standard_LRS"
20  }
21}

Step 8: Deploy the Virtual Machine with Terraform

1️⃣ Authenticate with Azure

Log in using the Azure CLI:

1az login

If you have multiple subscriptions, set the correct one:

1az account list --output table
2az account set --subscription "Your Subscription Name"

2️⃣ Initialize Terraform

Run terraform init to prepare Terraform for deployment:

1terraform init

3️⃣ Preview Changes with Terraform Plan

1terraform plan -out=tfplan

4️⃣ Apply the Terraform Configuration

1terraform apply tfplan

Step 9: Get the VM Public IP and Connect

Retrieve the public IP:

1terraform output

Use Remote Desktop (RDP) to connect to the Windows VM:

1mstsc /v:<VM_PUBLIC_IP>

Step 10: Clean Up Resources

1terraform destroy

Conclusion

We successfully deployed an Azure Virtual Machine using Terraform, covering:

Infrastructure as Code (IaC) principles
Defining a Virtual Network, Subnet, and Public IP
Deploying a Windows VM securely
Running Terraform commands to manage resources

Next Steps:

🔹 Use Azure Key Vault to store secrets securely.
🔹 Implement remote state management using Azure Storage.
🔹 Set up CI/CD pipelines with GitHub Actions for automated deployments.

🚀 Have any questions or suggestions? Drop them in the comments! 💬

🔥 Want to automate more Azure resources? Stay tuned for future Terraform guides! 🚀