TerraformPilot

Terraform

Terraform on Azure: A Complete Beginner's Guide

A beginner-friendly Terraform Azure guide with provider setup, resource groups, VNets, VMs, and remote state. Step-by-step with code examples.

LLuca Berton1 min read

Quick Answer

#

Install Terraform, log in with az login, configure the azurerm provider with an empty features {} block, and run terraform init && terraform plan && terraform apply. Azure resources need a Resource Group first — everything goes inside one.

Prerequisites

#
# Install Azure CLI
curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash
az login
az account show  # Verify subscription
 
# Install Terraform
terraform version

Step 1: Provider Configuration

#
terraform {
  required_version = ">= 1.5"
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "~> 3.90"
    }
  }
}
 
provider "azurerm" {
  features {}  # Required — even if empty
}

Step 2: Resource Group

#

Every Azure resource lives in a Resource Group:

resource "azurerm_resource_group" "main" {
  name     = "terraform-demo-rg"
  location = "East US"
}
terraform init
terraform plan
terraform apply

Step 3: Virtual Network

#
resource "azurerm_virtual_network" "main" {
  name                = "demo-vnet"
  address_space       = ["10.0.0.0/16"]
  location            = azurerm_resource_group.main.location
  resource_group_name = azurerm_resource_group.main.name
}
 
resource "azurerm_subnet" "app" {
  name                 = "app-subnet"
  resource_group_name  = azurerm_resource_group.main.name
  virtual_network_name = azurerm_virtual_network.main.name
  address_prefixes     = ["10.0.1.0/24"]
}

Step 4: Linux Virtual Machine

#
resource "azurerm_network_interface" "web" {
  name                = "web-nic"
  location            = azurerm_resource_group.main.location
  resource_group_name = azurerm_resource_group.main.name
 
  ip_configuration {
    name                          = "internal"
    subnet_id                     = azurerm_subnet.app.id
    private_ip_address_allocation = "Dynamic"
  }
}
 
resource "azurerm_linux_virtual_machine" "web" {
  name                = "web-vm"
  resource_group_name = azurerm_resource_group.main.name
  location            = azurerm_resource_group.main.location
  size                = "Standard_B2s"
  admin_username      = "azureuser"
 
  network_interface_ids = [azurerm_network_interface.web.id]
 
  admin_ssh_key {
    username   = "azureuser"
    public_key = file("~/.ssh/id_rsa.pub")
  }
 
  os_disk {
    caching              = "ReadWrite"
    storage_account_type = "Standard_LRS"
  }
 
  source_image_reference {
    publisher = "Canonical"
    offer     = "0001-com-ubuntu-server-jammy"
    sku       = "22_04-lts"
    version   = "latest"
  }
}

Step 5: Remote State with Azure Blob

#
# Create storage for state
az group create --name terraform-state-rg --location eastus
az storage account create --name tfstatemycompany \
  --resource-group terraform-state-rg --sku Standard_LRS
az storage container create --name tfstate --account-name tfstatemycompany
terraform {
  backend "azurerm" {
    resource_group_name  = "terraform-state-rg"
    storage_account_name = "tfstatemycompany"
    container_name       = "tfstate"
    key                  = "demo.terraform.tfstate"
  }
}

Azure Key Concepts for Terraform

#
Azure ConceptPurposeTerraform Resource
Resource GroupContainer for resourcesazurerm_resource_group
Virtual NetworkNetworkingazurerm_virtual_network
SubnetNetwork segmentazurerm_subnet
NSGFirewall rulesazurerm_network_security_group
VMComputeazurerm_linux_virtual_machine
Storage AccountBlob/file storageazurerm_storage_account

Clean Up

#
terraform destroy  # Removes all resources

Next Steps

# #

Conclusion

#

Terraform on Azure follows the same init → plan → apply workflow as other clouds. Start with a Resource Group, add networking, then compute. Use Azure Blob Storage for remote state. The azurerm provider requires a features {} block — even if empty.

#Terraform#Azure#DevOps#Infrastructure as Code#Beginner

Share this article