🌐 Introduction
If you’ve worked with AWS before, you might already know how powerful Terraform can be for defining infrastructure as code (IaC). But did you know the same principles apply seamlessly to Azure? In this post, we’ll walk through how to use Terraform to create a Linux virtual machine in Microsoft Azure, step by step.
Whether you’re a cloud beginner or an experienced engineer exploring multi-cloud deployments, this example will help you understand the building blocks of provisioning infrastructure in Azure.
🧱 1. What Terraform Does
Terraform is an Infrastructure as Code (IaC) tool that lets you describe your infrastructure in simple configuration files and then automatically build it in the cloud.
Instead of manually creating VMs and networks in the Azure Portal, you write a .tf file, run a few commands, and Terraform does the rest.
Think of it like version-controlling your cloud infrastructure.
⚙️ 2. Prerequisites
Before you start:
- Install Terraform
- Install the Azure CLI
- Run
az loginto authenticate to your Azure account - Have an SSH key pair ready (
~/.ssh/id_rsa.pub)
🧩 3. Setting Up Your Terraform Files
We’ll create two simple files:
providers.tf– defines the Azure providermain.tf– contains the infrastructure definition
🧰 providers.tf
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~> 4.0"
}
}
required_version = ">= 1.6.0"
}
provider "azurerm" {
features {}
}
This block tells Terraform that we’ll be using Azure and which provider plugin to download.
☁️ main.tf
Here’s a minimal setup to create:
- Resource group
- Virtual network and subnet
- Public IP
- Network security group
- Network interface
- Linux VM
resource "azurerm_resource_group" "rg" {
name = "rg-terraform-demo"
location = "eastus"
}
resource "azurerm_virtual_network" "vnet" {
name = "vnet-demo"
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 = "subnet-demo"
resource_group_name = azurerm_resource_group.rg.name
virtual_network_name = azurerm_virtual_network.vnet.name
address_prefixes = ["10.0.1.0/24"]
}
resource "azurerm_public_ip" "public_ip" {
name = "publicip-demo"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
allocation_method = "Static"
}
resource "azurerm_network_security_group" "nsg" {
name = "nsg-demo"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
security_rule {
name = "allow_ssh"
priority = 1001
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
destination_port_range = "22"
source_port_range = "*"
source_address_prefix = "*"
destination_address_prefix = "*"
}
}
resource "azurerm_network_interface" "nic" {
name = "nic-demo"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
ip_configuration {
name = "nic-ipconfig"
subnet_id = azurerm_subnet.subnet.id
private_ip_address_allocation = "Dynamic"
public_ip_address_id = azurerm_public_ip.public_ip.id
}
}
resource "azurerm_linux_virtual_machine" "vm" {
name = "vm-demo"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
size = "Standard_B1s"
admin_username = "azureuser"
network_interface_ids = [azurerm_network_interface.nic.id]
admin_ssh_key {
username = "azureuser"
public_key = file("~/.ssh/id_rsa.pub")
}
os_disk {
name = "osdisk-demo"
caching = "ReadWrite"
storage_account_type = "Standard_LRS"
}
source_image_reference {
publisher = "Canonical"
offer = "0001-com-ubuntu-server-jammy"
sku = "22_04-lts"
version = "latest"
}
disable_password_authentication = true
}
output "public_ip" {
value = azurerm_public_ip.public_ip.ip_address
}
🚀 4. Deploying Your Azure VM
Run the following commands in your terminal:
terraform init
terraform plan
terraform apply
Terraform will show you what it plans to build — type yes to confirm.
After a few minutes, you’ll see your VM’s public IP in the output.
Connect to it via SSH:
ssh azureuser@<public_ip>
🧠 5. Wrap-Up
Congratulations! 🎉 You’ve just provisioned a Linux VM in Azure with Terraform.
You now have the foundation to automate:
- App deployments
- Storage and networking setup
- Scalable infrastructure pipelines
From here, try adding:
- Tags for cost tracking
- Port 80/443 rules for web servers
- Auto-shutdown policies
Infrastructure as Code makes it easy to replicate, version, and scale your environments with minimal effort — whether it’s AWS, Azure, or Google Cloud.
