Skip to content

Terraform module composition (feature) for ARM Windows Virtual Machine (VM)

License

Notifications You must be signed in to change notification settings

claranet/terraform-azurerm-windows-vm

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Azure Windows Virtual Machine

Changelog Notice Apache V2 License OpenTofu Registry

This module creates a Windows Virtual Machine with Windows Remote Management (WinRM) activated.

The Windows Virtual Machine comes with:

This code is mostly based on Tom Harvey work: https://github.com/terraform-providers/terraform-provider-azurerm/tree/master/examples/virtual-machines/provisioners/windows

Following tags are automatically set with default values: env, stack, os_family, os_distribution, os_version.

Limitations

  • A self-signed certificate is generated and associated

Requirements

Ansible usage

The created virtual machine can be used with Ansible this way.

ansible all -i <public_ip_address>, -m win_ping -e ansible_user=<vm_username> -e ansible_password==<vm_password> -e ansible_connection=winrm -e ansible_winrm_server_cert_validation=ignore

Global versioning rule for Claranet Azure modules

Module version Terraform version OpenTofu version AzureRM version
>= 8.x.x Unverified 1.8.x >= 4.0
>= 7.x.x 1.3.x >= 3.0
>= 6.x.x 1.x >= 3.0
>= 5.x.x 0.15.x >= 2.0
>= 4.x.x 0.13.x / 0.14.x >= 2.0
>= 3.x.x 0.12.x >= 2.0
>= 2.x.x 0.12.x < 2.0
< 2.x.x 0.11.x < 2.0

Contributing

If you want to contribute to this repository, feel free to use our pre-commit git hook configuration which will help you automatically update and format some files for you by enforcing our Terraform code module best-practices.

More details are available in the CONTRIBUTING.md file.

Usage

This module is optimized to work with the Claranet terraform-wrapper tool which set some terraform variables in the environment needed by this module. More details about variables set by the terraform-wrapper available in the documentation.

⚠️ Since modules version v8.0.0, we do not maintain/check anymore the compatibility with Hashicorp Terraform. Instead, we recommend to use OpenTofu.

module "azure_region" {
  source  = "claranet/regions/azurerm"
  version = "x.x.x"

  azure_region = var.azure_region
}

module "rg" {
  source  = "claranet/rg/azurerm"
  version = "x.x.x"

  location    = module.azure_region.location
  client_name = var.client_name
  environment = var.environment
  stack       = var.stack
}

module "azure_network_vnet" {
  source  = "claranet/vnet/azurerm"
  version = "x.x.x"

  environment    = var.environment
  location       = module.azure_region.location
  location_short = module.azure_region.location_short
  client_name    = var.client_name
  stack          = var.stack

  resource_group_name = module.rg.resource_group_name
  vnet_cidr           = ["10.10.0.0/16"]
}

module "azure_network_subnet" {
  source  = "claranet/subnet/azurerm"
  version = "x.x.x"

  environment    = var.environment
  location_short = module.azure_region.location_short
  client_name    = var.client_name
  stack          = var.stack

  resource_group_name  = module.rg.resource_group_name
  virtual_network_name = module.azure_network_vnet.virtual_network_name
  subnet_cidr_list     = ["10.10.10.0/24"]

  route_table_name = module.azure_network_route_table.route_table_name

  network_security_group_name = module.network_security_group.network_security_group_name
}

module "network_security_group" {
  source  = "claranet/nsg/azurerm"
  version = "x.x.x"

  client_name         = var.client_name
  environment         = var.environment
  stack               = var.stack
  resource_group_name = module.rg.resource_group_name
  location            = module.azure_region.location
  location_short      = module.azure_region.location_short

  winrm_inbound_allowed = true
  allowed_winrm_source  = var.admin_ip_addresses # "*"
}

module "azure_network_route_table" {
  source  = "claranet/route-table/azurerm"
  version = "x.x.x"

  client_name         = var.client_name
  environment         = var.environment
  stack               = var.stack
  location            = module.azure_region.location
  location_short      = module.azure_region.location_short
  resource_group_name = module.rg.resource_group_name
}

resource "azurerm_availability_set" "vm_avset" {
  name                = "${var.stack}-${var.client_name}-${module.azure_region.location_short}-${var.environment}-as"
  location            = module.azure_region.location
  resource_group_name = module.rg.resource_group_name
  managed             = true
}

module "run" {
  source  = "claranet/run/azurerm"
  version = "x.x.x"

  client_name         = var.client_name
  location            = module.azure_region.location
  location_short      = module.azure_region.location_short
  environment         = var.environment
  stack               = var.stack
  resource_group_name = module.rg.resource_group_name

  monitoring_function_enabled = false
  vm_monitoring_enabled       = true
  backup_vm_enabled           = true
  update_center_enabled       = true

  update_center_periodic_assessment_enabled = true
  update_center_periodic_assessment_scopes  = [module.rg.resource_group_id]
  update_center_maintenance_configurations = [
    {
      configuration_name = "Donald"
      start_date_time    = "2021-08-21 04:00"
      recur_every        = "1Day"
    },
    {
      configuration_name = "Hammer"
      start_date_time    = "1900-01-01 03:00"
      recur_every        = "1Week"
    }
  ]

  recovery_vault_cross_region_restore_enabled = true
  vm_backup_daily_policy_retention            = 31

  keyvault_enabled_for_deployment = true
  keyvault_admin_objects_ids      = var.keyvault_admin_objects_ids
}

module "vm" {
  source  = "claranet/windows-vm/azurerm"
  version = "x.x.x"

  location            = module.azure_region.location
  location_short      = module.azure_region.location_short
  client_name         = var.client_name
  environment         = var.environment
  stack               = var.stack
  resource_group_name = module.rg.resource_group_name

  key_vault_id   = module.run.keyvault_id
  subnet_id      = module.azure_network_subnet.subnet_id
  vm_size        = "Standard_B2s"
  admin_username = var.vm_administrator_login
  admin_password = var.vm_administrator_password

  diagnostics_storage_account_name      = module.run.logs_storage_account_name
  azure_monitor_data_collection_rule_id = module.run.data_collection_rule_id

  # Set to null to deactivate backup
  backup_policy_id = module.run.vm_backup_policy_id

  patch_mode                    = "AutomaticByPlatform"
  maintenance_configuration_ids = [module.run.maintenance_configurations["Donald"].id, module.run.maintenance_configurations["Hammer"].id]

  availability_set_id = azurerm_availability_set.vm_avset.id
  # or use Availability Zone
  # zone_id = 1

  vm_image = {
    publisher = "MicrosoftWindowsServer"
    offer     = "WindowsServer"
    sku       = "2019-Datacenter-with-Containers"
    version   = "latest"
  }

  # The feature must be activated upstream:
  # az feature register --namespace Microsoft.Compute --name EncryptionAtHost --subscription <subscription_id_or_name>
  encryption_at_host_enabled = true

  # Use unmanaged disk if needed
  # If those blocks are not defined, it will use managed_disks
  os_disk_size_gb = "150" # At least 127 Gb
  os_disk_caching = "ReadWrite"

  storage_data_disk_config = {
    app = {
      disk_size_gb         = 256
      lun                  = 0
      storage_account_type = "Premium_LRS"
    }
  }

  aad_login_enabled = true
  aad_login_user_objects_ids = [
    data.azuread_group.vm_users_group.object_id
  ]

  aad_login_admin_objects_ids = [
    data.azuread_group.vm_admins_group.object_id
  ]
}

# Retrieve the existing AAD groups to which we want to assign login access on this Windows VM.
data "azuread_group" "vm_admins_group" {
  display_name = "Virtual Machines Administrators"
}

data "azuread_group" "vm_users_group" {
  display_name = "Virtual Machines Basic Users"
}

Providers

Name Version
azurecaf ~> 1.2, >= 1.2.22
azurerm ~> 3.108
null ~> 3.0

Modules

Name Source Version
azure_region claranet/regions/azurerm ~> 7.2.0
vm_os_disk_tagging claranet/tagging/azurerm 6.0.2

Resources

Name Type
azurerm_backup_protected_vm.backup resource
azurerm_key_vault_access_policy.vm resource
azurerm_key_vault_certificate.winrm_certificate resource
azurerm_maintenance_assignment_virtual_machine.maintenance_configurations resource
azurerm_managed_disk.disk resource
azurerm_monitor_data_collection_rule_association.dcr resource
azurerm_network_interface.nic resource
azurerm_network_interface_application_gateway_backend_address_pool_association.appgw_pool_association resource
azurerm_network_interface_backend_address_pool_association.lb_pool_association resource
azurerm_network_interface_security_group_association.nic_nsg_association resource
azurerm_public_ip.public_ip resource
azurerm_role_assignment.rbac_admin_login resource
azurerm_role_assignment.rbac_user_login resource
azurerm_virtual_machine_data_disk_attachment.data_disk_attachment resource
azurerm_virtual_machine_extension.aad_login resource
azurerm_virtual_machine_extension.azure_monitor_agent resource
azurerm_virtual_machine_extension.diagnostics resource
azurerm_virtual_machine_extension.keyvault_certificates resource
azurerm_virtual_machine_extension.log_extension resource
azurerm_windows_virtual_machine.vm resource
null_resource.winrm_connection_test resource
azurecaf_name.disk data source
azurecaf_name.hostname data source
azurecaf_name.nic data source
azurecaf_name.pub_ip data source
azurecaf_name.vm data source
azurerm_client_config.current data source
azurerm_managed_disk.vm_os_disk data source

Inputs

Name Description Type Default Required
aad_login_admin_objects_ids Azure Active Directory objects IDs allowed to connect as administrator on the VM. list(string) [] no
aad_login_enabled Enable login against Azure Active Directory. bool false no
aad_login_extension_version VM Extension version for Azure Active Directory Login extension. string "1.0" no
aad_login_user_objects_ids Azure Active Directory objects IDs allowed to connect as standard user on the VM. list(string) [] no
admin_password Password for Virtual Machine administrator account. string n/a yes
admin_username Username for Virtual Machine administrator account. string n/a yes
application_gateway_backend_pool_id Id of the Application Gateway Backend Pool to attach the VM. string null no
attach_application_gateway True to attach this VM to an Application Gateway. bool false no
attach_load_balancer True to attach this VM to a Load Balancer. bool false no
availability_set_id Id of the availability set in which host the Virtual Machine. string null no
azure_monitor_agent_auto_upgrade_enabled Automatically update agent when publisher releases a new version of the agent. bool false no
azure_monitor_agent_user_assigned_identity User Assigned Identity to use with Azure Monitor Agent. string null no
azure_monitor_agent_version Azure Monitor Agent extension version (https://learn.microsoft.com/en-us/azure/azure-monitor/agents/azure-monitor-agent-extension-versions). string "1.13" no
azure_monitor_data_collection_rule_id Data Collection Rule ID from Azure Monitor for metrics and logs collection. Used with new monitoring agent, set to null if legacy agent is used. string n/a yes
backup_policy_id Backup policy ID from the Recovery Vault to attach the Virtual Machine to (value to null to disable backup). string n/a yes
certificate_validity_in_months The created certificate validity in months number 48 no
client_name Client name/account used in naming. string n/a yes
custom_computer_name Custom name for the Virtual Machine Hostname. Based on custom_name if not set. string "" no
custom_data The Base64-Encoded Custom Data which should be used for this Virtual Machine. Changing this forces a new resource to be created. string null no
custom_dcr_name Custom name for Data collection rule association string null no
custom_dns_label The DNS label to use for public access. VM name if not set. DNS will be .westeurope.cloudapp.azure.com. string "" no
custom_ipconfig_name Custom name for the IP config of the NIC. Generated if not set. string null no
custom_name Custom name for the Virtual Machine. Generated if not set. string "" no
custom_nic_name Custom name for the NIC interface. Generated if not set. string null no
custom_public_ip_name Custom name for public IP. Generated if not set. string null no
default_tags_enabled Option to enable or disable default tags. bool true no
diagnostics_storage_account_key Access key of the Storage Account used for Virtual Machine diagnostics. Used only with legacy monitoring agent, set to null if not needed. string null no
diagnostics_storage_account_name Name of the Storage Account in which store boot diagnostics and for legacy monitoring agent. string null no
encryption_at_host_enabled Should all disks (including the temporary disk) attached to the Virtual Machine be encrypted by enabling Encryption at Host? List of compatible VM sizes: https://learn.microsoft.com/en-us/azure/virtual-machines/linux/disks-enable-host-based-encryption-cli#finding-supported-vm-sizes. bool false no
environment Project environment. string n/a yes
extensions_extra_tags Extra tags to set on the VM extensions. map(string) {} no
extra_tags Extra tags to set on each created resource. map(string) {} no
hotpatching_enabled Should the VM be patched without requiring a reboot? Possible values are true or false. bool false no
identity Map with identity block informations as described here https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/linux_virtual_machine#identity.
object({
type = string
identity_ids = list(string)
})
{
"identity_ids": [],
"type": "SystemAssigned"
}
no
key_vault_certificates_names List of Azure Key Vault certificates names to install in the VM. list(string) null no
key_vault_certificates_polling_rate Polling rate (in seconds) for Key Vault certificates retrieval. number 300 no
key_vault_certificates_store_name Name of the cetrificate store on which install the Key Vault certificates. string "MY" no
key_vault_id Id of the Azure Key Vault to use for VM certificate (value to null to disable winrm certificate). string n/a yes
license_type Specifies the BYOL Type for this Virtual Machine. Possible values are Windows_Client and Windows_Server if set. string null no
load_balancer_backend_pool_id Id of the Load Balancer Backend Pool to attach the VM. string null no
location Azure location. string n/a yes
location_short Short string for Azure location. string n/a yes
log_analytics_agent_enabled Deploy Log Analytics VM extension - depending of OS (cf. https://docs.microsoft.com/fr-fr/azure/azure-monitor/agents/agents-overview#linux) bool false no
log_analytics_agent_version Azure Log Analytics extension version. string "1.0" no
log_analytics_workspace_guid GUID of the Log Analytics Workspace to link with. string null no
log_analytics_workspace_key Access key of the Log Analytics Workspace to link with. string null no
maintenance_configuration_ids List of maintenance configurations to attach to this VM. list(string) [] no
name_prefix Optional prefix for the generated name. string "" no
name_suffix Optional suffix for the generated name. string "" no
nic_accelerated_networking_enabled Should Accelerated Networking be enabled? Defaults to false. bool false no
nic_extra_tags Extra tags to set on the network interface. map(string) {} no
nic_nsg_id NSG ID to associate on the Network Interface. No association if null. string null no
os_disk_caching Specifies the caching requirements for the OS Disk. string "ReadWrite" no
os_disk_custom_name Custom name for OS disk. Generated if not set. string null no
os_disk_extra_tags Extra tags to set on the OS disk. map(string) {} no
os_disk_overwrite_tags True to overwrite existing OS disk tags instead of merging. bool false no
os_disk_size_gb Specifies the size of the OS disk in gigabytes. string null no
os_disk_storage_account_type The Type of Storage Account which should back this the Internal OS Disk. Possible values are Standard_LRS, StandardSSD_LRS, Premium_LRS, StandardSSD_ZRS and Premium_ZRS. string "Premium_ZRS" no
os_disk_tagging_enabled Should OS disk tagging be enabled? Defaults to true. bool true no
patch_mode Specifies the mode of in-guest patching to this Windows Virtual Machine. Possible values are Manual, AutomaticByOS and AutomaticByPlatform. It also active path assessment when set to AutomaticByPlatform string "AutomaticByOS" no
patching_reboot_setting Specifies the reboot setting for platform scheduled patching. Possible values are Always, IfRequired and Never. string "IfRequired" no
public_ip_extra_tags Extra tags to set on the public IP resource. map(string) {} no
public_ip_sku Sku for the public IP attached to the VM. Can be null if no public IP needed. string "Standard" no
public_ip_zones Zones for public IP attached to the VM. Can be null if no zone distpatch. list(number)
[
1,
2,
3
]
no
resource_group_name Resource group name. string n/a yes
spot_instance True to deploy VM as a Spot Instance bool false no
spot_instance_eviction_policy Specifies what should happen when the Virtual Machine is evicted for price reasons when using a Spot instance. At this time the only supported value is Deallocate. Changing this forces a new resource to be created. string "Deallocate" no
spot_instance_max_bid_price The maximum price you're willing to pay for this VM in US Dollars; must be greater than the current spot price. -1 If you don't want the VM to be evicted for price reasons. number -1 no
stack Project stack name. string n/a yes
static_private_ip Static private IP. Private IP is dynamic if not set. string null no
storage_data_disk_config Map of objects to configure storage data disk(s).
map(object({
name = optional(string)
create_option = optional(string, "Empty")
disk_size_gb = number
lun = optional(number)
caching = optional(string, "ReadWrite")
storage_account_type = optional(string, "StandardSSD_ZRS")
source_resource_id = optional(string)
extra_tags = optional(map(string), {})
}))
{} no
subnet_id ID of the Subnet in which create the Virtual Machine. string n/a yes
use_caf_naming Use the Azure CAF naming provider to generate default resource name. custom_name override this if set. Legacy default name is used if this is set to false. bool true no
use_legacy_monitoring_agent True to use the legacy monitoring agent instead of Azure Monitor Agent. bool false no
user_data The Base64-Encoded User Data which should be used for this Virtual Machine. string null no
vm_image Virtual Machine source image information. See https://www.terraform.io/docs/providers/azurerm/r/windows_virtual_machine.html#source_image_reference. map(string)
{
"offer": "WindowsServer",
"publisher": "MicrosoftWindowsServer",
"sku": "2019-Datacenter",
"version": "latest"
}
no
vm_image_id The ID of the Image which this Virtual Machine should be created from. This variable supersedes the vm_image variable if not null. string null no
vm_plan Virtual Machine plan image information. See https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/linux_virtual_machine#plan. This variable has to be used for BYOS image. Before using BYOS image, you need to accept legal plan terms. See https://docs.microsoft.com/en-us/cli/azure/vm/image?view=azure-cli-latest#az_vm_image_accept_terms.
object({
name = string
product = string
publisher = string
})
null no
vm_size Size (SKU) of the Virtual Machine to create. string n/a yes
zone_id Index of the Availability Zone which the Virtual Machine should be allocated in. number null no

Outputs

Name Description
maintenance_configurations_assignments Maintenance configurations assignments configurations.
terraform_module Information about this Terraform module
vm_admin_password Windows Virtual Machine administrator account password
vm_admin_username Windows Virtual Machine administrator account username
vm_hostname Hostname of the Virtual Machine
vm_id ID of the Virtual Machine
vm_identity Identity block with principal ID
vm_name Name of the Virtual Machine
vm_nic_id ID of the Network Interface Configuration attached to the Virtual Machine
vm_nic_ip_configuration_name Name of the IP Configuration for the Network Interface Configuration attached to the Virtual Machine
vm_nic_name Name of the Network Interface Configuration attached to the Virtual Machine
vm_private_ip_address Private IP address of the Virtual Machine
vm_public_domain_name_label Public DNS of the Virtual machine
vm_public_ip_address Public IP address of the Virtual Machine
vm_public_ip_id Public IP ID of the Virtual Machine
vm_winrm_certificate_data The raw Key Vault Certificate.
vm_winrm_certificate_key_vault_id Id of the generated certificate in the input Key Vault
vm_winrm_certificate_thumbprint The X509 Thumbprint of the Key Vault Certificate returned as hex string.

Related documentation

Microsoft Azure documentation: docs.microsoft.com/en-us/azure/virtual-machines/windows/