IaC

Deploy A Simple Windows VM (101-vm-simple-windows) Using Terraform

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… Visualized in ARMVIZ Deployed resources Configuration variables.tf 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." } main.tf 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 } Deploy the configuration Authentication 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. Initialization 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 Plan Terraform will check for the syntax errors and generates the execution plan, you can also save this plan for your future deployments terraform plan Apply To apply the configuration run the command below… terraform apply


28 December 2018