Create an Azure VM using Terraform.
Terraform is currently one of the most popular infrastructure automation tool to manage multi cloud environment. This blog post will show case using Terraform to create a resource and Virtual Machine in Azure.
This configuration file will create following resources in Azure.
- 1. Resourcegroup
- 2. Virtual Network
- 3. Subnet
- 4. Network Security Group
- 5. Virtual Machine
mian.tf
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = ">=2.6"
}
}
}
provider "azurerm" {
version = ">=2.6"
client_id = "var.client_id"
client_secret = "var.client_secret"
subscription_id = "var.subscription_id"
tenant_id = "var.tenant_id"
features {}
}
resource "azurerm_resource_group" "rg" {
name = "LearnTerraform"
location = var.location
}
resource "azurerm_virtual_network" "vnet" {
name = "LearnTerraform-Vnet"
resource_group_name = azurerm_resource_group.rg.name
location = azurerm_resource_group.rg.location
address_space = [var.vnet_address_range]
}
resource "azurerm_subnet" "web" {
name = "LearnTerraform-subnet"
resource_group_name = azurerm_resource_group.rg.name
virtual_network_name = azurerm_virtual_network.vnet.name
address_prefixes = [var.subnet_address_range]
}
resource "azurerm_network_security_group" "nsg" {
name = "LearnTerraform-nsg"
resource_group_name = azurerm_resource_group.rg.name
location = azurerm_resource_group.rg.location
security_rule {
name = "Allow_RDP"
priority = 1000
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_port_range = "*"
destination_port_range = 3389
source_address_prefix = "10.0.1.10"
destination_address_prefix = "*"
}
}
resource "azurerm_subnet_network_security_group_association" "subnet-nsg" {
subnet_id = azurerm_subnet.web.id
network_security_group_id = azurerm_network_security_group.nsg.id
}
resource "azurerm_public_ip" "pip" {
name = "winvm-public-
resource_group_name = azurerm_resource_group.rg.name
location = azurerm_resource_group.rg.location
allocation_method = var.allocation_method[0]
}
resource "azurerm_network_interface" "nic" {
name = "LearnTerraform-wimvm-nic"
resource_group_name = azurerm_resource_group.rg.name
location = azurerm_resource_group.rg.location
ip_configuration {
name = "wimvm-nic-ipconfig"
subnet_id = azurerm_subnet.web.id
public_ip_address_id = azurerm_public_ip.pip.id
private_ip_address_allocation = var.allocation_method[1]
}
}
resource "azurerm_windows_virtual_machine" "vm" {
name = "LearnTerraform-winvm"
resource_group_name = azurerm_resource_group.rg.name
location = azurerm_resource_group.rg.location
network_interface_ids = [azurerm_network_interface.nic.id]
size = var.virtual_machine_size
computer_name = var.computer_name
admin_username = var.admin_username
admin_password = var.admin_password
os_disk {
name = "winvm-os-disk"
caching = var.os_disk_caching
storage_account_type = var.os_disk_storage_account_type
disk_size_gb = var.os_disk_size_gb
}
source_image_reference {
publisher = var.publisher
offer = var.offer
sku = var.sku
version = var.vm_image_version
}
}
variables.tf
variable "client_id" {
description = "This is the application id from the service principal in Azure AD"
type = string
}
variable "client_secret" {
description = "This is the secret for the service principal in Azure AD"
type = string
}
variable "subscription_id" {
description = "The guid for the subscription id"
type = string
}
variable "tenant_id" {
description = "This is the tenant id for your Azure AD instance"
type = string
}
# Resource Group
variable "location" {
description = "Location of the resource group"
type = string
default = "australiaeast"
}
# Vnet and Subnet
variable "vnet_address_range" {
description = "IP Range of the virtual network"
type = string
default = "10.0.0.0/16"
}
variable "subnet_address_range" {
description = "IP Range of the virtual network"
type = string
default = "10.0.1.0/24"
}
# Public IP and NIC Allocation Method
variable "allocation_method" {
description = "Allocation method for Public IP Address and NIC Private ip address"
type = list(string)
default = ["Static", "Dynamic"]
}
# VM
variable "virtual_machine_size" {
description = "Size of the VM"
type = string
default = "Standard_B1s"
}
variable "computer_name" {
description = "Computer name"
type = string
default = "Win10vm"
}
variable "admin_username" {
description = "Username to login to the VM"
type = string
default = "winadmin"
}
variable "admin_password" {
description = "Password to login to the VM"
type = string
default = "P@$$w0rD2021*"
}
variable "os_disk_caching" {
default = "ReadWrite"
}
variable "os_disk_storage_account_type" {
default = "StandardSSD_LRS"
}
variable "os_disk_size_gb" {
default = 128
}
variable "publisher" {
default = "MicrosoftWindowsDesktop"
}
variable "offer" {
default = "Windows-10"
}
variable "sku" {
default = "rs5-pro-g2"
}
variable "vm_image_version" {
default = "latest"
}
output.tf
output "resource-names" {
description = "Print the names of the resources"
value = {
"Resource-Group-Name" = azurerm_resource_group.rg.name
"Vnet-Name" = azurerm_virtual_network.vnet.name
"Subnet-Name" = azurerm_subnet.web.name
"NSG-Name" = azurerm_network_security_group.nsg.name
"NIC-Name" = azurerm_network_interface.nic.name
}
}
output "public_ip_address" {
value = azurerm_public_ip.pip.ip_address
}
output "vm_login" {
description = "Credentials to login to the VM"
value = {
"VM-Name" = azurerm_windows_virtual_machine.vm.name
"Username" = azurerm_windows_virtual_machine.vm.admin_username
"Password" = azurerm_windows_virtual_machine.vm.admin_password
}
sensitive= true
}
In this article I learned to develop terraform configuration file and deploy Azure resources.