Skip to content

qbeyond/terraform-azurerm-windows-vm

Repository files navigation

Windows VM

GitHub tag License


This module will create a windows virtual machine, a network interface and associates the network interface to the target subnet. Optionally one or more data disks and a public ip can be created.

Usage

This module provisions a windows virtual machine. Refer to the examples on how this could be done. It is a fast and easy to use deployment of a virtual machine!

Examples

Basic
provider "azurerm" {
  features {}
}

module "virtual_machine" {
  source = "../.."
  virtual_machine_config = {
    hostname             = "CUSTAPP001"
    location             = local.location
    admin_username       = "local_admin"
    size                 = "Standard_B1s"
    os_sku               = "2022-Datacenter"
    os_version           = "latest"
    os_disk_storage_type = "Standard_LRS"
  }
  admin_password      = "H3ll0W0rld!"
  resource_group_name = azurerm_resource_group.this.name
  subnet              = azurerm_subnet.this
  severity_group      = "01-first-monday-2000-csu-reboot"
}

resource "azurerm_resource_group" "this" {
  name     = local.resource_group_name
  location = local.location
}

resource "azurerm_virtual_network" "this" {
  name                = local.virtual_network_name
  address_space       = ["10.0.0.0/24"]
  location            = azurerm_resource_group.this.location
  resource_group_name = azurerm_resource_group.this.name
}

resource "azurerm_subnet" "this" {
  name                 = local.subnet_name
  resource_group_name  = azurerm_resource_group.this.name
  virtual_network_name = azurerm_virtual_network.this.name
  address_prefixes     = ["10.0.0.0/24"]
}
Advanced
provider "azurerm" {
  features {}
}

module "virtual_machine" {
  source = "../.."
  public_ip_config = {
    enabled           = true
    allocation_method = "Static"
  }
  nic_config = {
    private_ip                    = "10.0.0.16"
    dns_servers                   = ["10.0.0.10", "10.0.0.11"]
    enable_accelerated_networking = true
    nsg                           = azurerm_network_security_group.this
  }
  virtual_machine_config = {
    hostname                     = "CUSTAPP007"
    location                     = azurerm_resource_group.this.location
    size                         = "Standard_B1s"
    os_sku                       = "2022-datacenter-g2"
    os_version                   = "latest"
    os_disk_name                 = "DiskOverride"
    os_disk_size_gb              = 128
    os_disk_caching              = "ReadWrite"
    os_disk_storage_type         = "Standard_LRS"
    os_disk_write_accelerator_enabled = false
    availability_set_id          = azurerm_availability_set.this.id
    proximity_placement_group_id = azurerm_proximity_placement_group.this.id

    admin_username               = "loc_admin"

    timezone                     = "Azores Standard Time"

    patch_assessment_mode                                  = "AutomaticByPlatform"
    patch_mode                                             = "AutomaticByPlatform"
    bypass_platform_safety_checks_on_user_schedule_enabled = true

    tags = {
      "Environment" = "prd"
    }
  }
  admin_password      = "H3ll0W0rld!"
  resource_group_name = azurerm_resource_group.this.name
  subnet              = azurerm_subnet.this
  data_disks = {
    "${local.managed_disk_name}" = {
      lun                       = 1
      caching                   = "ReadWrite"
      disk_size_gb              = 64
      create_option             = "Empty"
      storage_account_type      = "Standard_LRS"
      write_accelerator_enabled = false
    }
  }

  additional_network_interface_ids = [azurerm_network_interface.additional_nic_01.id]
  severity_group                   = "01-third-tuesday-0200-XCSUFEDTG-reboot"
  update_allowed                   = true

  name_overrides = {
    nic             = local.nic
    nic_ip_config   = local.nic_ip_config
    public_ip       = local.public_ip
    virtual_machine = local.virtual_machine
    data_disks = {
      "${local.managed_disk_name}" = "Override"
    }
  }

  tags = {
    "example" = "examplevalue"
  }
}

resource "azurerm_resource_group" "this" {
  name     = local.resource_group_name
  location = local.location
}

resource "azurerm_virtual_network" "this" {
  name                = local.virtual_network_name
  address_space       = ["10.0.0.0/24"]
  location            = azurerm_resource_group.this.location
  resource_group_name = azurerm_resource_group.this.name
}

resource "azurerm_subnet" "this" {
  name                 = local.subnet_name
  resource_group_name  = azurerm_resource_group.this.name
  virtual_network_name = azurerm_virtual_network.this.name
  address_prefixes     = ["10.0.0.0/24"]
}

resource "azurerm_availability_set" "this" {
  name                         = local.availability_set_name
  location                     = local.location
  resource_group_name          = azurerm_resource_group.this.name
  proximity_placement_group_id = azurerm_proximity_placement_group.this.id
}

resource "azurerm_proximity_placement_group" "this" {
  name                = local.proximity_placement_group_name
  location            = local.location
  resource_group_name = azurerm_resource_group.this.name
  
  lifecycle {
      ignore_changes = [tags]
  }
}

resource "azurerm_network_interface" "additional_nic_01" {
  name                          = "nic-vm-${replace(element(azurerm_virtual_network.this.address_space,0), "/[./]/", "-")}-01"
  location                      = local.location
  resource_group_name           = azurerm_resource_group.this.name
  dns_servers                   = []

  ip_configuration {
    name                          = "ip-nic-01"
    subnet_id                     = azurerm_subnet.this.id
    private_ip_address_allocation = "Dynamic"
    private_ip_address            = null
    public_ip_address_id          = null
  }

  lifecycle {
    ignore_changes = [
      tags
    ]
  }
}

resource "azurerm_network_security_group" "this" {
  name                = local.nsg_name
  location            = local.location
  resource_group_name = azurerm_resource_group.this.name

  security_rule {
    name                       = "example"
    priority                   = 100
    direction                  = "Outbound"
    access                     = "Allow"
    protocol                   = "Tcp"
    source_port_range          = "*"
    destination_port_range     = "*"
    source_address_prefix      = "*"
    destination_address_prefix = "*"
  }
}

Requirements

Name Version
azurerm >= 3.7.0

Inputs

Name Description Type Default Required
admin_password Password of the local administrator. string n/a yes
resource_group_name Name of the resource group where the resources will be created. string n/a yes
severity_group The severity group of the virtual machine. Added as value of tag Severity Group Monthly. string n/a yes
subnet The variable takes the subnet as input and takes the id and the address prefix for further configuration.
object({
id = string
address_prefixes = list(string)
})
n/a yes
virtual_machine_config
hostname: Name of the host system.
size: The size of the vm. Possible values can be seen here: https://learn.microsoft.com/en-us/azure/virtual-machines/sizes
location: The location of the virtual machine.
os_sku: The os that will be running on the vm.
os_version: Optionally specify an os version for the chosen sku. Defaults to latest.
os_disk_caching: Optionally change the caching option of the os disk. Defaults to ReadWrite.
os_disk_storage_type: Optionally change the os_disk_storage_type. Defaults to StandardSSD_LRS.
os_disk_size_gb: Optionally change the size of the os disk. Defaults to be specified by image.
admin_username: Optionally choose the admin_username of the vm. Defaults to loc_sysadmin.
The local admin name could be changed by the gpo in the target ad.
os_disk_write_accelerator_enabled: Optionally activate write accelaration for the os disk. Can only
be activated on Premium_LRS disks and caching deactivated. Defaults to false.
timezone: Optionally change the timezone of the VM. Defaults to UTC.
(More timezone names: https://jackstromberg.com/2017/01/list-of-time-zones-consumed-by-azure/).
zone: Optionally specify an availibility zone for the vm.
availability_set_id: Optionally specify an availibilty set for the vm.
proximity_placement_group_id: (Optional) The ID of the Proximity Placement Group which the Virtual Machine should be assigned to.
patch_assessment_mode: Specifies the mode of VM Guest Patching for the Virtual Machine.
patch_mode: Specifies the mode of in-guest patching to this Windows Virtual Machine.
bypass_platform_safety_checks_on_user_schedule_enabled: This setting ensures that machines are patched by using your configured schedules and not autopatched.
Can only be set to true when patch_mode is set to AutomaticByPlatform.
object({
hostname = string
size = string
location = string
os_sku = string
os_version = optional(string, "latest")
os_disk_caching = optional(string, "ReadWrite")
os_disk_storage_type = optional(string, "StandardSSD_LRS")
os_disk_size_gb = optional(number)
os_disk_write_accelerator_enabled = optional(bool, false)
admin_username = optional(string, "loc_sysadmin")
timezone = optional(string, "UTC")
zone = optional(string)
availability_set_id = optional(string)
proximity_placement_group_id = optional(string)
patch_assessment_mode = optional(string, "AutomaticByPlatform")
patch_mode = optional(string, "AutomaticByPlatform")
bypass_platform_safety_checks_on_user_schedule_enabled = optional(bool, true)
})
n/a yes
additional_network_interface_ids List of ids for additional azurerm_network_interface. list(string) [] no
data_disks
 = {
lun: Number of the lun.
disk_size_gb: The size of the data disk.
storage_account_type: Optionally change the storage_account_type. Defaults to StandardSSD_LRS.
caching: Optionally activate disk caching. Defaults to None.
create_option: Optionally change the create option. Defaults to Empty disk.
source_resource_id: (Optional) The ID of an existing Managed Disk or Snapshot to copy when create_option is Copy or
the recovery point to restore when create_option is Restore. Changing this forces a new resource to be created.
write_accelerator_enabled: Optionally activate write accelaration for the data disk. Can only
be activated on Premium disks and caching deactivated. Defaults to false.
on_demand_bursting_enabled: Optionally activate disk bursting. Only for Premium disk with size to 512 Gb up. Default false.
}
map(object({
lun = number
disk_size_gb = number
caching = optional(string, "ReadWrite")
create_option = optional(string, "Empty")
source_resource_id = optional(string)
storage_account_type = optional(string, "StandardSSD_LRS")
write_accelerator_enabled = optional(bool, false)
on_demand_bursting_enabled = optional(bool, false)
}))
{} no
name_overrides Possibility to override names that will be generated according to q.beyond naming convention.
object({
nic = optional(string)
nic_ip_config = optional(string)
public_ip = optional(string)
virtual_machine = optional(string)
os_disk = optional(string)
data_disks = optional(map(string), {})
})
{} no
nic_config
private_ip: Optioanlly specify a private ip to use. Otherwise it will  be allocated dynamically.
dns_servers: Optionally specify a list of dns servers for the nic.
enable_accelerated_networking: Enabled Accelerated networking (SR-IOV) on the NIC. The machine SKU must support this feature.
nsg: Although it is discouraged you can optionally assign an NSG to the NIC. Optionally specify a NSG object.
object({
private_ip = optional(string)
dns_servers = optional(list(string))
enable_accelerated_networking = optional(bool, false)
nsg = optional(object({
id = string
}))
})
{} no
public_ip_config
enabled: Optionally select true if a public ip should be created. Defaults to false.
allocation_method: The allocation method of the public ip that will be created. Defaults to static.
object({
enabled = bool
allocation_method = optional(string, "Static")
})
{
"enabled": false
}
no
tags A mapping of tags to add to the resources created in this module map(string) {} no
update_allowed Set the tag Update allowed. True will set yes, false to no. bool true no

Outputs

Name Description
data_disks n/a
network_interface n/a
virtual_machine n/a
  ## Resource types

  | Type | Used |
  |------|-------|
    | [azurerm_managed_disk](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/managed_disk) | 1 |
    | [azurerm_network_interface](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/network_interface) | 1 |
    | [azurerm_network_interface_security_group_association](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/network_interface_security_group_association) | 1 |
    | [azurerm_public_ip](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/public_ip) | 1 |
    | [azurerm_virtual_machine_data_disk_attachment](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_machine_data_disk_attachment) | 1 |
    | [azurerm_windows_virtual_machine](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/windows_virtual_machine) | 1 |

  **`Used` only includes resource blocks.** `for_each` and `count` meta arguments, as well as resource blocks of modules are not considered.

Modules

No modules.

    ## Resources by Files

        ### data_disk.tf

        | Name | Type |
        |------|------|
              | [azurerm_managed_disk.data_disk](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/managed_disk) | resource |
              | [azurerm_virtual_machine_data_disk_attachment.data_disk](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_machine_data_disk_attachment) | resource |

        ### main.tf

        | Name | Type |
        |------|------|
              | [azurerm_network_interface.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/network_interface) | resource |
              | [azurerm_network_interface_security_group_association.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/network_interface_security_group_association) | resource |
              | [azurerm_public_ip.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/public_ip) | resource |
              | [azurerm_windows_virtual_machine.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/windows_virtual_machine) | resource |

Contribute

Please use Pull requests to contribute.

When a new Feature or Fix is ready to be released, create a new Github release and adhere to Semantic Versioning 2.0.0.