This terraform configuration will deploy a simple Windows VM on Azure cloud, and this is a conversion of
101-vm-simple-windows
from
azure_quickstart_templates.
This configuration consists of two .tf
files (variables.tf
and main.tf
) and deploy a single vm with the following resources…
Variables are separated from the main configuration, and this configuration accepts the variable below…
provider "azurerm" {
version = "=1.36.0"
}
variable "resourceGroupName" {
type = string
description = "Resource Group for this deployment."
}
variable "location" {
type = string
description = "Location for all resources"
}
variable "adminUsername" {
type = string
description = "Username for the Virtual Machine."
}
variable "adminPassword" {
type = string
description = "Password for the Virtual Machine."
}
variable "dnsLabelPrefix" {
type = string
description = "Unique DNS Name for the Public IP used to access the Virtual Machine."
}
variable "windowsOSVersion" {
type = list
default = ["2016-Datacenter","2008-R2-SP1","2012-Datacenter","2012-R2-Datacenter","2016-Nano-Server","2016-Datacenter-with-Containers","2019-Datacenter"]
description = "The Windows version for the VM. This will pick a fully patched image of this given Windows version."
}
variable "vmSize" {
type = string
default = "Standard_A2_v2"
description = "Size of the virtual machine."
}
This file contains the actual configuration to create a simple Windows VM…
# Declaring the local variables
locals {
storageAccountName = lower(join("", ["sawinvm", random_string.asaname-01.result]))
nicName = "myVMNic"
addressPrefix = "10.0.0.0/16"
subnetName = "Subnet"
subnetPrefix = "10.0.0.0/24"
publicIPAddressName = "myPublicIP"
vmName = "SimpleWinVM"
virtualNetworkName = "MyVNET"
networkSecurityGroupName = "default-NSG"
osDiskName = join("",[local.vmName, "_OsDisk_1_", lower(random_string.avmosd-01.result)])
}
# Generating the random string to create a unique storage account
resource "random_string" "asaname-01" {
length = 16
special = "false"
}
# Generating the random string to create a unique os disk
resource "random_string" "avmosd-01" {
length = 32
special = "false"
}
# Resource Group
resource "azurerm_resource_group" "arg-01" {
name = var.resourceGroupName
location = var.location
}
# Storage Account
resource "azurerm_storage_account" "asa-01" {
name = local.storageAccountName
resource_group_name = azurerm_resource_group.arg-01.name
location = azurerm_resource_group.arg-01.location
account_replication_type = "LRS"
account_tier = "Standard"
}
# Public IP
resource "azurerm_public_ip" "apip-01" {
name = local.publicIPAddressName
resource_group_name = azurerm_resource_group.arg-01.name
location = azurerm_resource_group.arg-01.location
allocation_method = "Dynamic"
domain_name_label = var.dnsLabelPrefix
}
# Network Security Group with allow RDP rule
resource "azurerm_network_security_group" "ansg-01" {
name = local.networkSecurityGroupName
resource_group_name = azurerm_resource_group.arg-01.name
location = azurerm_resource_group.arg-01.location
security_rule {
name = "default-allow-3389"
priority = 1000
access = "Allow"
direction = "Inbound"
destination_port_range = 3389
protocol = "Tcp"
source_port_range = "*"
source_address_prefix = "*"
destination_address_prefix = "*"
}
}
# Virtual Network
resource "azurerm_virtual_network" "avn-01" {
name = local.virtualNetworkName
resource_group_name = azurerm_resource_group.arg-01.name
location = azurerm_resource_group.arg-01.location
address_space = [local.addressPrefix]
}
# Subnet
resource "azurerm_subnet" "as-01" {
name = local.subnetName
resource_group_name = azurerm_resource_group.arg-01.name
virtual_network_name = azurerm_virtual_network.avn-01.name
address_prefix = local.subnetPrefix
}
# Associate the subnet with NSG
resource "azurerm_subnet_network_security_group_association" "asnsga-01" {
subnet_id = azurerm_subnet.as-01.id
network_security_group_id = azurerm_network_security_group.ansg-01.id
}
# Network Interface Card
resource "azurerm_network_interface" "anic-01" {
name = local.nicName
resource_group_name = azurerm_resource_group.arg-01.name
location = azurerm_resource_group.arg-01.location
ip_configuration {
name = "ipconfig1"
private_ip_address_allocation = "Dynamic"
public_ip_address_id = azurerm_public_ip.apip-01.id
subnet_id = azurerm_subnet.as-01.id
}
}
# Virtual Machine
resource "azurerm_virtual_machine" "avm-01" {
name = local.vmName
resource_group_name = azurerm_resource_group.arg-01.name
location = azurerm_resource_group.arg-01.location
vm_size = var.vmSize
network_interface_ids = [azurerm_network_interface.anic-01.id]
os_profile {
computer_name = local.vmName
admin_username = var.adminUsername
admin_password = var.adminPassword
}
storage_image_reference {
publisher = "MicrosoftWindowsServer"
offer = "WindowsServer"
sku = var.windowsOSVersion[0]
version = "latest"
}
storage_os_disk {
name = local.osDiskName
create_option = "FromImage"
}
storage_data_disk {
name = "Data"
disk_size_gb = 1023
lun = 0
create_option = "Empty"
}
os_profile_windows_config {
provision_vm_agent = true
}
boot_diagnostics {
enabled = true
storage_uri = azurerm_storage_account.asa-01.primary_blob_endpoint
}
}
# Print virtual machine dns name
output "hostname" {
value = azurerm_public_ip.apip-01.fqdn
}
Please use AzureCli to authenticate to your Azure cloud environment, terraform can use the same session to deploy the resources. Check here for alternate methods of authentication.
First time you need to initialize the configuration directory, where it will download the necessary plugins to deploy the current configuration, to initialize you need to run the command below…
terraform init
Terraform will check for the syntax errors and generates the execution plan, you can also save this plan for your future deployments
terraform plan
To apply the configuration run the command below…
terraform apply