This is a write-up for creating a linux virtual machine in Azure Cloud using Terraform. Pre-requisites: Azure cloud account, Azure CLI installed on local machine, Azure configure with required access to build and manage vm in Azure cloud, Azure provider.
We will create an ubuntu virtual machine with public IP access to ssh and http port 80 for viewing default apache home page.
Azure resource group
resource "azurerm_resource_group" "vmtask" { name = "rg-task4" location = "eastus2" }
Azure Public IP
resource "azurerm_public_ip" "vmtask" { name = "vmtask-public-ip" resource_group_name = azurerm_resource_group.vmtask.name location = azurerm_resource_group.vmtask.location allocation_method = "Static" tags = { environment = "demo" } }
Azure virtual network
resource "azurerm_virtual_network" "vmtask" { name = "vnet-task4" address_space = ["10.0.0.0/16"] location = azurerm_resource_group.vmtask.location resource_group_name = azurerm_resource_group.vmtask.name } resource "azurerm_subnet" "vmtask" { name = "subnet-task4" resource_group_name = azurerm_resource_group.vmtask.name virtual_network_name = azurerm_virtual_network.vmtask.name address_prefixes = ["10.0.2.0/24"] }
Network Security Group: Below snippet will create two security rules to open port 22 and port 80.
resource "azurerm_network_security_group" "vmtask" { name = "vmtasknsg" resource_group_name = azurerm_resource_group.vmtask.name location = azurerm_resource_group.vmtask.location security_rule { name = "SSH" priority = 100 direction = "Inbound" access = "Allow" protocol = "Tcp" source_port_range = "*" destination_port_range = "22" source_address_prefix = "*" destination_address_prefix = "*" } security_rule { name = "http" priority = 101 direction = "Inbound" access = "Allow" protocol = "Tcp" source_port_range = "*" destination_port_range = "80" source_address_prefix = "*" destination_address_prefix = "*" } tags = { environment = "demo" } }
Network Security Group association:
resource "azurerm_subnet_network_security_group_association" "vmtask" { subnet_id = azurerm_subnet.vmtask.id network_security_group_id = azurerm_network_security_group.vmtask.id }
Network interface:
resource "azurerm_network_interface" "vmtask" { name = "vmtask-nic" location = azurerm_resource_group.vmtask.location resource_group_name = azurerm_resource_group.vmtask.name ip_configuration { name = "internal" subnet_id = azurerm_subnet.vmtask.id private_ip_address_allocation = "Dynamic" public_ip_address_id = azurerm_public_ip.vmtask.id } }
Create virtual machine
resource "azurerm_linux_virtual_machine" "vmtask" { name = "vmtask-ubuntu" resource_group_name = azurerm_resource_group.vmtask.name location = azurerm_resource_group.vmtask.location size = "Standard_F2" admin_username = "adminuser" admin_password = "********" disable_password_authentication = false network_interface_ids = [ azurerm_network_interface.vmtask.id, ] 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" } }
Output Public IP
output "public_ip_address" { value = azurerm_public_ip.vmtask.ip_address description = "The public IP address of the virtual machine" }
Terraform's declarative syntax makes it easy to define complex infrastructure setups and manage them efficiently.