Creating Azure Resources with Terraform: A Step-by-Step Guide

Jaseetha Satkurunathan
4 min readOct 27, 2023

--

This tutorial provides a comprehensive and easy-to-follow guide on how to use Terraform to create Azure resources. Whether you are a beginner or an experienced user, this tutorial will walk you through the process, from setting up your Azure account to deploying your first resource.

Prerequires

  1. Azure Account
  2. Azure CLI
  3. Terraform 0.14.9 or later
  4. Terraform for Beginners

Install Azure CLI in Linux

sudo rpm --import https://packages.microsoft.com/keys/microsoft.asc
sudo sh -c 'echo -e "[azure-cli]\nname=Azure CLI\nbaseurl=https://packages.microsoft.com/yumrepos/azure-cli\nenabled=1\ngpgcheck=1\ngpgkey=https://packages.microsoft.com/keys/microsoft.asc" > /etc/yum.repos.d/azure-cli.repo'
sudo yum install -y azure-cli

How to Install Terraform in RHEL, CentOS & Fedora Linux machine

$ sudo yum install -y yum-utils
#### Below $release is "RHEL", "AmazonLinux", or "fedora" As per your OS #####
$ sudo yum-config-manager --add-repo https://rpm.releases.hashicorp.com/$release/hashicorp.repo
$ sudo yum update
$ sudo yum install terraform
###### -------- Verify Installation ---------- ######
$ terraform version

How to login your Azure Subscription and authenticate

az login
az account set --subscription <SUBSCRIPTION_ID>

Create a provider.tf file as below

terraform {
required_version = ">= 0.12" # Specify the required Terraform version constraint
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 3.0, < 4.0" # Specify the required AWS provider version constraint
}
azure = {
source = "hashicorp/azurerm"
version = "~> 2.0" # Specify the required Azure provider version constraint
}
# Add more providers with their respective version constraints if needed
}
}

# Configure the Microsoft Azure Provider
provider "azurerm" {
features {}
}

The terraform {} block in above configuration sets Terraform's global settings, including specifying the required providers for the infrastructure. Each provider is defined with a source attribute that identifies where to fetch the provider. By default, Terraform fetches providers from the Terraform Registry .

The required_providers block is optional, it's recommended to use it to ensure our configuration works with a specific provider version. Without version constraints, Terraform may automatically use the latest provider version

The provider block configures the specified provider, in this case azurerm. Essential Terraform plugins linking code to cloud resources

Start creating below deployment using terraform

Create main.tf file as below

resource "azurerm_resource_group" "demo_rg" {
name = "RG_RnD_Demo_Terraform"
location = "West Europe"
}

resource "azurerm_virtual_network" "demo_vnet" {
name = "vnet_terr_demo"
address_space = ["10.0.0.0/16"]
location = azurerm_resource_group.demo_rg.location
resource_group_name = azurerm_resource_group.demo_rg.name
}

resource "azurerm_subnet" "demo_subnet1" {
name = "vm_terr_demo"
resource_group_name = azurerm_resource_group.demo_rg.name
virtual_network_name = azurerm_virtual_network.demo_vnet.name
address_prefixes = ["10.0.1.0/24"]
}

resource "azurerm_subnet" "demo_subnet2" {
name = "db_terr_demo"
resource_group_name = azurerm_resource_group.demo_rg.name
virtual_network_name = azurerm_virtual_network.demo_vnet.name
address_prefixes = ["10.0.2.0/24"]
}

resource "azurerm_network_interface" "demo_nic" {
name = "vm_terr_demo"
location = azurerm_resource_group.demo_rg.location
resource_group_name = azurerm_resource_group.demo_rg.name

ip_configuration {
name = "vm_demo"
subnet_id = azurerm_subnet.demo_subnet1.id
private_ip_address_allocation = "Dynamic"
}
}

resource "azurerm_linux_virtual_machine" "demo_vm" {
name = "vmdemo"
resource_group_name = azurerm_resource_group.demo_rg.name
location = azurerm_resource_group.demo_rg.location
size = "Standard_F2"
admin_username = "adminuser"
network_interface_ids = [
azurerm_network_interface.demo_nic.id,
]

admin_ssh_key {
username = "adminuser"
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-focal"
sku = "20_04-lts"
version = "latest"
}
}

Use resource blocks to define components of your infrastructure. A resource might be a physical component such as a server, resource group, network and etc. In above code each resource block will create single resources.

There are lots of ways to define variables and use. Here I am using hardcoded value for understanding the terraform .tf configuration. When a value is depend on previous resource need to follow order as shown in below image.

Initialize Terraform configuration

terraform init

Below screenshot is the output of initialization. It will automatically create a new file .terraform.lock.hcl. It is maintained automatically by “terraform init”.

Validate and create plan

terraform validate
terrafor plan -out vm.tfplan
output for terraform plan

Generate graph to view our plan

This step is optional. I am showing demo for easy understanding. for complex deployments we can use this to verify our plan.

terraform graph

You will get below output as digraph. In order view use Webgraphviz .

output of terraform graph
simulated graph

We are ready to deploy and create resource now.

terraform apply vm.tfplan

Resources has been successfully created. Lets verify from Azure portal.

This tutorial serves as a foundational guide for Terraform setup. Beyond these basics, advanced features exist to streamline and enhance your code. These include count, for_each, modules, and workspaces and Terraform Cloud. These advanced terraform empower you for efficient deployment across multiple environments.

--

--

Jaseetha Satkurunathan

DevOps Engineer | DevAIOps Enthusiast | Multi-cloud Architect