Skip to main content
How to Use Terraform with Azure - Complete Setup Guide

How to Use Terraform with Azure - Complete Setup Guide

Key Takeaway

Set up Terraform with Microsoft Azure from scratch. Covers Azure CLI login, service principal, provider configuration, resource groups, and first deployment.

Table of Contents

Quick Answer

Install Terraform, authenticate with Azure (CLI or service principal), configure the azurerm provider, and deploy. Service principals are recommended for CI/CD; Azure CLI login works for local development.

Prerequisites

# Install Azure CLI
curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash

# Login to Azure
az login

# Set your subscription
az account set --subscription "My Subscription"
az account show

Authentication Methods

Method 1: Azure CLI (Local Development)

provider "azurerm" {
  features {}
  # Uses your az login session automatically
}
# Create a service principal
az ad sp create-for-rbac --name "terraform-sp" \
  --role Contributor \
  --scopes "/subscriptions/YOUR_SUBSCRIPTION_ID"
provider "azurerm" {
  features {}
  subscription_id = var.subscription_id
  client_id       = var.client_id
  client_secret   = var.client_secret
  tenant_id       = var.tenant_id
}
# Set as environment variables (preferred over hardcoding)
export ARM_SUBSCRIPTION_ID="your-sub-id"
export ARM_CLIENT_ID="your-client-id"
export ARM_CLIENT_SECRET="your-client-secret"
export ARM_TENANT_ID="your-tenant-id"

Method 3: Managed Identity (Azure VMs/Pipelines)

provider "azurerm" {
  features {}
  use_msi = true
}

First Azure Resource

terraform {
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "~> 3.90"
    }
  }
}

provider "azurerm" {
  features {}
}

resource "azurerm_resource_group" "main" {
  name     = "myapp-prod-rg"
  location = "East US"
}

resource "azurerm_virtual_network" "main" {
  name                = "myapp-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"]
}
terraform init
terraform plan
terraform apply

Remote State with Azure Blob

# Create storage account for state
az storage account create --name myapptfstate --resource-group myapp-rg \
  --sku Standard_LRS --encryption-services blob

az storage container create --name tfstate --account-name myapptfstate
terraform {
  backend "azurerm" {
    resource_group_name  = "myapp-rg"
    storage_account_name = "myapptfstate"
    container_name       = "tfstate"
    key                  = "prod.terraform.tfstate"
  }
}

Common Azure Resources

# Linux VM
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"
  }
}

Azure vs AWS Terraform Comparison

ConceptAWSAzure
Account isolationAWS AccountResource Group
NetworkingVPCVirtual Network
IdentityIAMAzure AD + RBAC
StorageS3Blob Storage
ComputeEC2Virtual Machines
Providerhashicorp/awshashicorp/azurerm
Auth env varsAWS_ACCESS_KEY_IDARM_CLIENT_ID

Troubleshooting

ErrorFix
AuthorizationFailedAssign Contributor role to SP
SubscriptionNotFoundCheck ARM_SUBSCRIPTION_ID
features {} requiredAdd empty features {} block to provider
MissingSubscriptionSet subscription: az account set

Conclusion

Terraform with Azure works best with service principals for CI/CD and Azure CLI for local development. Start with a resource group, add networking, then build up. Use Azure Blob Storage for remote state with locking.

🚀

Level Up Your Terraform Skills

Hands-on courses, books, and resources from Luca Berton

Luca Berton
Written by

Luca Berton

DevOps Engineer, AWS Partner, Terraform expert, and author. Creator of Ansible Pilot, Terraform Pilot, and CopyPasteLearn.