Skip to content

Coalfire-CF/terraform-azurerm-vm-windows

Coalfire

terraform-azurerm-vm-windows

This module is used in the Coalfire-Azure-RAMPpak FedRAMP Framework. It will create a Windows Virtual Machine using managed disks.

Learn more at Coalfire OpenSource.

Dependencies

  • Security Core
  • Region Setup

Resource List

  • VM
  • VM Nic
  • Public IP (optional)
  • AKV secret
  • Diagnostics extension
  • Network watcher extension

Deployment Steps

This module can be called as outlined below.

  • Change directories to the Bastion directory.
  • From the /terraform/prod/us-va/mgmt/bastion directory run terraform init.
  • Run terraform plan to review the resources being created.
  • If everything looks correct in the plan output, run terraform apply.

Usage with source_image_reference

provider "azurerm" {
  features {}
}

module "bastion1" {
  source = "github.com/Coalfire-CF/terraform-azurerm-vm-windows"

  vm_name                       = "${local.vm_name_prefix}ba1"
  vm_admin_username             = var.vm_admin_username
  location                      = var.location
  resource_group_name           = data.terraform_remote_state.core.outputs.core_rg_name
  size                          = "Standard_DS2_v2"
  enable_public_ip              = true
  subnet_id                     = data.terraform_remote_state.usgv_mgmt_vnet.outputs.usgv_mgmt_vnet_subnet_ids["${local.resource_prefix}-bastion-sn-1"]
  private_ip_address_allocation = "Dynamic"
  vm_diag_sa                    = data.terraform_remote_state.setup.outputs.vmdiag_endpoint
  storage_account_vmdiag_name   = data.terraform_remote_state.setup.outputs.storage_account_vmdiag_name
  kv_id                         = data.terraform_remote_state.core.outputs.core_kv_id
  trusted_launch                = false # For now, we are not using trusted launch. Fails with the CIS marketplace image.

  regional_tags                 = var.regional_tags
  global_tags                   = var.global_tags

  source_image_reference = {
    publisher = "center-for-internet-security-inc"
    offer     = "cis-win-2019-stig"
    sku       = "cis-win-2019-stig"
    version   = "latest"
  }

  plan = {
    publisher = "center-for-internet-security-inc"
    name      = "cis-win-2019-stig"
    product   = "cis-win-2019-stig"
  }

  vm_tags = {
    OS       = "Windows_STIG_2019"
    Function = "Bastion"
    Plane    = "Management"
  }
}

Usage with source_image_id

provider "azurerm" {
  features {}
}

module "bastion_custom" {
  source = "github.com/Coalfire-CF/terraform-azurerm-vm-windows"

  vm_name                       = "${local.vm_name_prefix}ba1"
  vm_admin_username             = var.vm_admin_username
  location                      = var.location
  resource_group_name           = data.terraform_remote_state.core.outputs.core_rg_name
  size                          = "Standard_DS2_v2"
  enable_public_ip              = true
  subnet_id                     = data.terraform_remote_state.usgv_mgmt_vnet.outputs.usgv_mgmt_vnet_subnet_ids["${local.resource_prefix}-bastion-sn-1"]
  private_ip_address_allocation = "Dynamic"
  vm_diag_sa                    = data.terraform_remote_state.setup.outputs.vmdiag_endpoint
  storage_account_vmdiag_name   = data.terraform_remote_state.setup.outputs.storage_account_vmdiag_name
  kv_id                         = data.terraform_remote_state.core.outputs.core_kv_id
  trusted_launch                = false

  regional_tags                 = var.regional_tags
  global_tags                   = var.global_tags

  source_image_id               = data.terraform_remote_state.setup.outputs.vm_image_definitions["win-server2022-golden"]
  source_image_reference        = null

  vm_tags = {
    OS       = "Windows_SIG"
    Function = "Bastion"
    Plane    = "Management"
  }
}

Requirements

No requirements.

Providers

Name Version
azurerm n/a
random n/a
time n/a

Modules

No modules.

Resources

Name Type
azurerm_key_vault_secret.xadm_pass resource
azurerm_monitor_data_collection_rule.ama_dcr resource
azurerm_monitor_data_collection_rule_association.ama_dcr_assoc resource
azurerm_network_interface.nic resource
azurerm_public_ip.public_ip resource
azurerm_role_assignment.custom_assignments resource
azurerm_role_assignment.dj_kv_assignment resource
azurerm_role_assignment.sa_install_assignment resource
azurerm_virtual_machine_extension.ama resource
azurerm_virtual_machine_extension.custom_extension resource
azurerm_virtual_machine_extension.vm_network_watcher resource
azurerm_windows_virtual_machine.vm resource
random_password.lap resource
time_sleep.wait_180_seconds resource
azurerm_log_analytics_workspace.log_analytics data source

Inputs

Name Description Type Default Required
ama_settings Optional settings to pass to the Azure Monitor Agent extension map(any) {} no
availability_set_id Azure Availability VM should be attached to string null no
availability_zone Specifies an Availability Zone in which the Windows VM should be located list(number) null no
custom_dns_label The DNS label to use for public access. VM name if not set. DNS will be .eastus2.cloudapp.azure.com string "" no
custom_role_assignments n/a
list(object({
scope = string
role = string
}))
[] no
custom_scripts Custom scripts with its arguments. Will be added to custom script extension. string "" no
custom_scripts_fileUris List with storage URLs to download custom scripts list(string) null no
disk_caching Type of caching used for Internal OS Disk - Must be one of [None, ReadOnly, ReadWrite] string "ReadWrite" no
disk_size Size of the Disk number 127 no
dj_kv_name Key Vault name containing the domain join user password string null no
domain_join Map with information required to join the vm to the domain
object({
domain_name = string
disname = string
windows_admins_ad_group = string
user_name = string
azure_cloud = string
windows_domainjoin_url = string
dj_kv_id = string
})
null no
enable_public_ip True/False if a Public IP Address should be attached to the VM bool n/a yes
global_tags Global level tags map(string) n/a yes
is_domain_join n/a bool false no
kv_id Key Vault Resource ID to store local admin password string null no
la_name Log analytics workspace name string n/a yes
la_resource_group_name Log analytics resource group name string n/a yes
location Azure region for resource deployment string n/a yes
performance_counters Performance counters to collect
list(object({
name = string
streams = list(string)
sampling_frequency_in_seconds = number
counter_specifiers = list(string)
}))
[
{
"counter_specifiers": [
"\Processor Information(_Total)\% Processor Time",
"\Processor Information(_Total)\% Privileged Time",
"\Processor Information(_Total)\% User Time",
"\Processor Information(_Total)\Processor Frequency",
"\System\Processes",
"\Process(_Total)\Thread Count",
"\Process(_Total)\Handle Count",
"\System\System Up Time",
"\System\Context Switches/sec",
"\System\Processor Queue Length",
"\Memory\% Committed Bytes In Use",
"\Memory\Available Bytes",
"\Memory\Committed Bytes",
"\Memory\Cache Bytes",
"\Memory\Pool Paged Bytes",
"\Memory\Pool Nonpaged Bytes",
"\Memory\Pages/sec",
"\Memory\Page Faults/sec",
"\Process(_Total)\Working Set",
"\Process(_Total)\Working Set - Private",
"\LogicalDisk(_Total)\% Disk Time",
"\LogicalDisk(_Total)\% Disk Read Time",
"\LogicalDisk(_Total)\% Disk Write Time",
"\LogicalDisk(_Total)\% Idle Time",
"\LogicalDisk(_Total)\Disk Bytes/sec",
"\LogicalDisk(_Total)\Disk Read Bytes/sec",
"\LogicalDisk(_Total)\Disk Write Bytes/sec",
"\LogicalDisk(_Total)\Disk Transfers/sec",
"\LogicalDisk(_Total)\Disk Reads/sec",
"\LogicalDisk(_Total)\Disk Writes/sec",
"\LogicalDisk(_Total)\Avg. Disk sec/Transfer",
"\LogicalDisk(_Total)\Avg. Disk sec/Read",
"\LogicalDisk(_Total)\Avg. Disk sec/Write",
"\LogicalDisk(_Total)\Avg. Disk Queue Length",
"\LogicalDisk(_Total)\Avg. Disk Read Queue Length",
"\LogicalDisk(_Total)\Avg. Disk Write Queue Length",
"\LogicalDisk(_Total)\% Free Space",
"\LogicalDisk(_Total)\Free Megabytes",
"\Network Interface()\Bytes Total/sec",
"\Network Interface(
)\Bytes Sent/sec",
"\Network Interface()\Bytes Received/sec",
"\Network Interface(
)\Packets/sec",
"\Network Interface()\Packets Sent/sec",
"\Network Interface(
)\Packets Received/sec",
"\Network Interface()\Packets Outbound Errors",
"\Network Interface(
)\Packets Received Errors"
],
"name": "windows-performance",
"sampling_frequency_in_seconds": 60,
"streams": [
"Microsoft-Perf"
]
}
]
no
plan Marketplace plan info — only required if using a Marketplace image that includes a plan.
object({
publisher = string
name = string
product = string
})
null no
private_ip Static Private IP address string "" no
private_ip_address_allocation Dynamic or Static string "Dynamic" no
public_ip_sku Sku for the public IP attached to the VM. Can be null if no public IP needed. string "Standard" no
regional_tags Regional level tags map(string) n/a yes
resource_group_name Azure Resource Group resource will be deployed in string n/a yes
sa_install_id Storage account id containing the install scripts string n/a yes
size Azure Virtual Machine size string "Standard_DS2_v2" no
source_image_id VM image from shared image gallery string null no
source_image_reference VM image from shared image gallery
object({
publisher = string
offer = string
sku = string
version = string
})
null no
storage_account_vmdiag_name Storage Account VM diagnostics are stored in string n/a yes
subnet_id ID of the subnet the VM NIC should be attached to string n/a yes
trusted_launch Enable Trusted Launch bool true no
vm_admin_username Local Administrator Name string n/a yes
vm_diag_sa Storage Account VM diagnostics are stored in string n/a yes
vm_hostname (Optional) Hostname for the virtual machine. Must be 15 characters or less. string null no
vm_name Azure Virtual Machine Name string n/a yes
vm_storage_account_type The Type of Storage Account which should back the OS Disk string "StandardSSD_LRS" no
vm_tags Key/Value tags that should be added to the VM map(string) {} no
windows_event_logs Windows Event Logs to collect
list(object({
name = string
streams = list(string)
x_path_queries = list(string)
}))
[
{
"name": "windows-events",
"streams": [
"Microsoft-Event"
],
"x_path_queries": [
"Application![System[(Level=1 or Level=2 or Level=3 or Level=4 or Level=0 or Level=5)]]",
"Security!
[System[(band(Keywords,13510798882111488))]]",
"System!*[System[(Level=1 or Level=2 or Level=3 or Level=4 or Level=0 or Level=5)]]"
]
}
]
no

Outputs

Name Description
network_interface_ids IDs of the VM NICs provisioned.
network_interface_private_ip Private IP addresses of the VM NICs
public_ip_address The IP address allocated for the resource.
public_ip_dns_name FQDN to connect to the first VM provisioned.
public_ip_id ID of the public IP address provisioned.
vm_id Virtual Machine Resource ID
vm_name Virtual Machine Name
vm_system_identity Virtual Machine System Managed Identity
vm_xadm_kv_name The name which the local admin password for the 'xadm' account is stored under in Key Vault

Contributing

Start Here

License

License

Contact Us

Coalfire

Copyright

Copyright © 2025 Coalfire Systems Inc.

About

Coalfire Azure Windows Virtual Machine Terraform Module

Topics

Resources

License

Code of conduct

Contributing

Stars

Watchers

Forks

Contributors 8

Languages