From 497c392d7b03381f35c7ecd52d153f5f0bc81640 Mon Sep 17 00:00:00 2001 From: "nilesh.gadgi" Date: Tue, 24 Jan 2023 15:50:09 +0530 Subject: [PATCH] added windows code --- README.yaml | 167 ++++++++++++++++++-------- _example/{ => linux-vm}/example.tf | 55 +++++---- _example/{ => linux-vm}/outputs.tf | 2 +- _example/windows-vm/example.tf | 184 +++++++++++++++++++++++++++++ _example/windows-vm/outputs.tf | 45 +++++++ main.tf | 103 ++++++++++++++-- variables.tf | 75 +++++++++++- 7 files changed, 546 insertions(+), 85 deletions(-) rename _example/{ => linux-vm}/example.tf (67%) rename _example/{ => linux-vm}/outputs.tf (94%) create mode 100644 _example/windows-vm/example.tf create mode 100644 _example/windows-vm/outputs.tf diff --git a/README.yaml b/README.yaml index fefeab7..5db9511 100644 --- a/README.yaml +++ b/README.yaml @@ -32,57 +32,128 @@ include: # How to use this project usage: |- Here are some examples of how you can use this module in your inventory structure: - ### Default vnet-peering + ### Linux Virtual Machine ```hcl module "virtual-machine" { source = "clouddrove/virtual-machine/azure" version = "1.0.0" - name = "app" - environment = "test" - label_order = ["name", "environment"] - ## Common - enabled = true - machine_count = 1 - resource_group_name = module.resource_group.resource_group_name - location = module.resource_group.resource_group_location - - ## Network Interface - subnet_id = module.subnet.default_subnet_id - private_ip_address_version = "IPv4" - private_ip_address_allocation = "Static" - primary = true - private_ip_addresses = ["10.0.1.4"] - #nsg - network_interface_sg_enabled = true - network_security_group_id = module.security_group.id - - ## Availability Set - availability_set_enabled = true - platform_update_domain_count = 7 - platform_fault_domain_count = 3 - - ## Public IP - public_ip_enabled = true - sku = "Basic" - allocation_method = "Static" - ip_version = "IPv4" - - ## Virtual Machine - linux_enabled = true - vm_size = "Standard_B1s" - file_path = "~/.ssh/id_rsa.pub" - username = "ubuntu" - os_profile_enabled = true - admin_username = "ubuntu" - create_option = "FromImage" - caching = "ReadWrite" - disk_size_gb = 30 - os_type = "Linux" - managed_disk_type = "Standard_LRS" - storage_image_reference_enabled = true - image_publisher = "Canonical" - image_offer = "UbuntuServer" - image_sku = "20.04-LTS" - image_version = "latest" + name = "app" + environment = "test" + label_order = ["environment", "name"] + + ## Common + is_vm_linux = true + enabled = true + machine_count = 1 + resource_group_name = module.resource_group.resource_group_name + location = module.resource_group.resource_group_location + disable_password_authentication = true + + ## Network Interface + subnet_id = module.subnet.default_subnet_id + private_ip_address_version = "IPv4" + private_ip_address_allocation = "Static" + primary = true + private_ip_addresses = ["10.0.1.4"] + #nsg + network_interface_sg_enabled = true + network_security_group_id = module.security_group.id + + ## Availability Set + availability_set_enabled = true + platform_update_domain_count = 7 + platform_fault_domain_count = 3 + + ## Public IP + public_ip_enabled = true + sku = "Basic" + allocation_method = "Static" + ip_version = "IPv4" + + + ## Virtual Machine + linux_enabled = true + vm_size = "Standard_B1s" + public_key = "ssh-rsa AAAAB3NzaC1yc2EoL9X+2+4Xb dev" # Enter valid public key here + username = "ubuntu" + os_profile_enabled = true + admin_username = "ubuntu" + # admin_password = "P@ssw0rd!123!" # It is compulsory when disable_password_authentication = false + create_option = "FromImage" + caching = "ReadWrite" + disk_size_gb = 30 + os_type = "Linux" + managed_disk_type = "Standard_LRS" + storage_image_reference_enabled = true + image_publisher = "Canonical" + image_offer = "0001-com-ubuntu-server-focal" + image_sku = "20_04-lts" + image_version = "latest" + } + ``` + ### Windows Virtual Machine + ```hcl + module "virtual-machine" { + source = "clouddrove/virtual-machine/azure" + version = "1.0.0" + name = "app" + environment = "test" + label_order = ["environment", "name"] + + ## Common + is_vm_windows = true + enabled = true + machine_count = 1 + resource_group_name = module.resource_group.resource_group_name + location = module.resource_group.resource_group_location + disable_password_authentication = false + create_option = "FromImage" + disk_size_gb = 128 + + + ## Network Interface + subnet_id = module.subnet.default_subnet_id + private_ip_address_version = "IPv4" + private_ip_address_allocation = "Static" + primary = true + private_ip_addresses = ["10.0.1.4"] + #nsg + network_interface_sg_enabled = true + network_security_group_id = module.security_group.id + + ## Availability Set + availability_set_enabled = true + platform_update_domain_count = 7 + platform_fault_domain_count = 3 + + ## Public IP + public_ip_enabled = true + sku = "Basic" + allocation_method = "Static" + ip_version = "IPv4" + + + os_type = "windows" + computer_name="app-win-comp" + + # windows_distribution_name = "windows2019dc" + vm_size = "Standard_B1s" + admin_username = "azureadmin" + admin_password = "Password@123" + image_publisher = "MicrosoftWindowsServer" + image_offer = "WindowsServer" + image_sku = "2019-Datacenter" + image_version = "latest" + + + enable_boot_diagnostics = false #Default is false + + data_disks = [ + { + name = "disk1" + disk_size_gb = 128 + storage_account_type = "StandardSSD_LRS" + } + ] } ``` diff --git a/_example/example.tf b/_example/linux-vm/example.tf similarity index 67% rename from _example/example.tf rename to _example/linux-vm/example.tf index 52e4452..72f8b3f 100644 --- a/_example/example.tf +++ b/_example/linux-vm/example.tf @@ -53,7 +53,7 @@ module "subnet" { } module "security_group" { -source = "clouddrove/network-security-group/azure" + source = "clouddrove/network-security-group/azure" version = "1.0.0" ## Tags name = "app" @@ -61,28 +61,28 @@ source = "clouddrove/network-security-group/azure" label_order = ["name", "environment"] ## Security Group - resource_group_name = module.resource_group.resource_group_name - resource_group_location = module.resource_group.resource_group_location - subnet_ids = module.subnet.default_subnet_id + resource_group_name = module.resource_group.resource_group_name + resource_group_location = module.resource_group.resource_group_location + subnet_ids = module.subnet.default_subnet_id ##Security Group rule for Custom port. inbound_rules = [ { - name = "ssh" - priority = 101 - access = "Allow" - protocol = "Tcp" - source_address_prefix = "0.0.0.0/0" - source_port_range = "*" - destination_address_prefix = "0.0.0.0/0" - destination_port_range = "22" - description = "ssh allowed port" -}] - + name = "ssh" + priority = 101 + access = "Allow" + protocol = "Tcp" + source_address_prefix = "0.0.0.0/0" + source_port_range = "*" + destination_address_prefix = "0.0.0.0/0" + destination_port_range = "22" + description = "ssh allowed port" + }] + } module "virtual-machine" { - source = "../" + source = "../../" ## Tags name = "app" @@ -90,10 +90,12 @@ module "virtual-machine" { label_order = ["environment", "name"] ## Common - enabled = true - machine_count = 1 - resource_group_name = module.resource_group.resource_group_name - location = module.resource_group.resource_group_location + is_vm_linux = true + enabled = true + machine_count = 1 + resource_group_name = module.resource_group.resource_group_name + location = module.resource_group.resource_group_location + disable_password_authentication = true ## Network Interface subnet_id = module.subnet.default_subnet_id @@ -118,12 +120,13 @@ module "virtual-machine" { ## Virtual Machine - linux_enabled = true - vm_size = "Standard_B1s" - public_key = "ssh-rsa AAAAB3NzaC1yc2EoL9X+2+4Xb dev" - username = "ubuntu" - os_profile_enabled = true - admin_username = "ubuntu" + linux_enabled = true + vm_size = "Standard_B1s" + public_key = "ssh-rsa AAAAB3NzaC1yc2EoL9X+2+4Xb dev" # Enter valid public key here + username = "ubuntu" + os_profile_enabled = true + admin_username = "ubuntu" + # admin_password = "P@ssw0rd!123!" # It is compulsory when disable_password_authentication = false create_option = "FromImage" caching = "ReadWrite" disk_size_gb = 30 diff --git a/_example/outputs.tf b/_example/linux-vm/outputs.tf similarity index 94% rename from _example/outputs.tf rename to _example/linux-vm/outputs.tf index a14a9c9..21a32d0 100644 --- a/_example/outputs.tf +++ b/_example/linux-vm/outputs.tf @@ -34,7 +34,7 @@ output "public_ip_address" { } output "virtual_machine_id" { - value = module.virtual-machine.virtual_machine_id + value = join("", module.virtual-machine.*.virtual_machine_id) description = "The ID of the Virtual Machine." } diff --git a/_example/windows-vm/example.tf b/_example/windows-vm/example.tf new file mode 100644 index 0000000..2a0d866 --- /dev/null +++ b/_example/windows-vm/example.tf @@ -0,0 +1,184 @@ +provider "azurerm" { + features {} +} + +module "resource_group" { + source = "clouddrove/resource-group/azure" + version = "1.0.0" + + name = "app-win-vm" + environment = "test" + label_order = ["name", "environment"] + location = "Canada Central" +} + +module "vnet" { + source = "clouddrove/vnet/azure" + version = "1.0.0" + + name = "app" + environment = "test" + label_order = ["name", "environment"] + resource_group_name = module.resource_group.resource_group_name + location = module.resource_group.resource_group_location + address_space = "10.0.0.0/16" + enable_ddos_pp = false +} + +module "subnet" { + source = "clouddrove/subnet/azure" + version = "1.0.1" + + name = "app" + environment = "test" + label_order = ["name", "environment"] + resource_group_name = module.resource_group.resource_group_name + location = module.resource_group.resource_group_location + virtual_network_name = join("", module.vnet.vnet_name) + + #subnet + default_name_subnet = true + subnet_names = ["subnet1", "subnet2"] + subnet_prefixes = ["10.0.1.0/24", "10.0.2.0/24"] + + # route_table + enable_route_table = false + routes = [ + { + name = "rt-test" + address_prefix = "0.0.0.0/0" + next_hop_type = "Internet" + } + ] +} + +module "security_group" { + source = "clouddrove/network-security-group/azure" + version = "1.0.0" + ## Tags + name = "app" + environment = "test" + label_order = ["name", "environment"] + + ## Security Group + resource_group_name = module.resource_group.resource_group_name + resource_group_location = module.resource_group.resource_group_location + subnet_ids = module.subnet.default_subnet_id + ##Security Group rule for Custom port. + inbound_rules = [ + { + name = "rdp" + priority = 101 + access = "Allow" + protocol = "Tcp" + source_address_prefix = "0.0.0.0/0" + source_port_range = "*" + destination_address_prefix = "0.0.0.0/0" + destination_port_range = "3389" + description = "allow rdp port" + }, + { + name = "http" + priority = 102 + access = "Allow" + protocol = "Tcp" + source_address_prefix = "0.0.0.0/0" + source_port_range = "*" + destination_address_prefix = "0.0.0.0/0" + destination_port_range = "443" + description = "allow https port" + } + ] + +} + + +module "virtual-machine" { + source = "../../" + + + # Resource Group, location, VNet and Subnet details + ## Tags + name = "app" + environment = "test" + label_order = ["environment", "name"] + + ## Common + is_vm_windows = true + enabled = true + machine_count = 1 + resource_group_name = module.resource_group.resource_group_name + location = module.resource_group.resource_group_location + disable_password_authentication = false + create_option = "FromImage" + disk_size_gb = 128 + + + ## Network Interface + subnet_id = module.subnet.default_subnet_id + private_ip_address_version = "IPv4" + private_ip_address_allocation = "Static" + primary = true + private_ip_addresses = ["10.0.1.4"] + #nsg + network_interface_sg_enabled = true + network_security_group_id = module.security_group.id + + ## Availability Set + availability_set_enabled = true + platform_update_domain_count = 7 + platform_fault_domain_count = 3 + + ## Public IP + public_ip_enabled = true + sku = "Basic" + allocation_method = "Static" + ip_version = "IPv4" + + + # This module support multiple Pre-Defined Linux and Windows Distributions. + # Check the README.md file for more pre-defined images for WindowsServer, MSSQLServer. + # Please make sure to use gen2 images supported VM sizes if you use gen2 distributions + # This module creates a random admin password if `admin_password` is not specified + # Specify a valid password with `admin_password` argument to use your own password + os_type = "windows" + computer_name = "app-win-comp" + + # windows_distribution_name = "windows2019dc" + vm_size = "Standard_B1s" + admin_username = "azureadmin" + admin_password = "Password@123" + image_publisher = "MicrosoftWindowsServer" + image_offer = "WindowsServer" + image_sku = "2019-Datacenter" + image_version = "latest" + + + # Boot diagnostics to troubleshoot virtual machines, by default uses managed + # To use custom storage account, specify `storage_account_name` with a valid name + # Passing a `null` value will utilize a Managed Storage Account to store Boot Diagnostics + enable_boot_diagnostics = false #Default is false + + # Attach a managed data disk to a Windows/Linux VM's. Possible Storage account type are: + # `Standard_LRS`, `StandardSSD_ZRS`, `Premium_LRS`, `Premium_ZRS`, `StandardSSD_LRS` + # or `UltraSSD_LRS` (UltraSSD_LRS only available in a region that support availability zones) + # Initialize a new data disk - you need to connect to the VM and run diskmanagemnet or fdisk + data_disks = [ + { + name = "disk1" + disk_size_gb = 128 + storage_account_type = "StandardSSD_LRS" + } + # ,{ + # name = "disk2" + # disk_size_gb = 200 + # storage_account_type = "Standard_LRS" + # } + ] + + # Deploy log analytics agents to virtual machine. + # Log analytics workspace customer id and primary shared key required. + # deploy_log_analytics_agent = true + # log_analytics_customer_id = data.azurerm_log_analytics_workspace.example.workspace_id + # log_analytics_workspace_primary_shared_key = data.azurerm_log_analytics_workspace.example.primary_shared_key +} \ No newline at end of file diff --git a/_example/windows-vm/outputs.tf b/_example/windows-vm/outputs.tf new file mode 100644 index 0000000..59ed079 --- /dev/null +++ b/_example/windows-vm/outputs.tf @@ -0,0 +1,45 @@ +output "resource_group_name" { + value = module.resource_group.resource_group_name + description = "The name of the resource group in which the subnet is created in." +} + +output "virtual_network_name" { + value = module.vnet.vnet_name + description = "The name of the virtual network in which the subnet is created in." +} + +output "subnet_id" { + value = module.subnet.default_subnet_id + description = "The subnet ID." +} + +output "network_interface_private_ip_addresses" { + value = module.virtual-machine.network_interface_private_ip_addresses + description = "The private IP addresses of the network interface." +} + + +output "availability_set_id" { + value = module.virtual-machine.availability_set_id + description = "The ID of the Availability Set." +} + +output "public_ip_id" { + value = module.virtual-machine.public_ip_id + description = "The Public IP ID." +} + +output "public_ip_address" { + value = module.virtual-machine.public_ip_address + description = "The IP address value that was allocated." +} + +output "virtual_machine_id" { + value = join("", module.virtual-machine.*.virtual_machine_id) + description = "The ID of the Virtual Machine." +} + +output "tags" { + value = module.virtual-machine.tags + description = "The tags associated to resources." +} diff --git a/main.tf b/main.tf index 814e483..84876e7 100644 --- a/main.tf +++ b/main.tf @@ -95,7 +95,7 @@ resource "azurerm_public_ip" "default" { #Module : LINUX VIRTUAL MACHINE #Description : Terraform resource to create a linux virtual machine. resource "azurerm_virtual_machine" "default" { - count = var.enabled ? var.machine_count : 0 + count = var.is_vm_linux ? var.machine_count : 0 name = format("%s-virtual-machine-%s", module.labels.id, count.index + 1) resource_group_name = var.resource_group_name location = var.location @@ -109,17 +109,17 @@ resource "azurerm_virtual_machine" "default" { zones = var.zones tags = module.labels.tags - dynamic "os_profile_linux_config" { - for_each = var.linux_enabled && var.disable_password_authentication ? [1] : [] + os_profile_linux_config { + # for_each = var.is_vm_linux && var.disable_password_authentication ? [1] : [] - content { - disable_password_authentication = var.disable_password_authentication + # content { + disable_password_authentication = var.disable_password_authentication - ssh_keys { - key_data = var.public_key - path = "/home/${var.username}/.ssh/authorized_keys" - } + ssh_keys { + key_data = var.public_key + path = "/home/${var.username}/.ssh/authorized_keys" } + # } } dynamic "boot_diagnostics" { @@ -232,6 +232,91 @@ resource "azurerm_virtual_machine" "default" { } + + +#Module : Windows VIRTUAL MACHINE +#Description : Terraform resource to create a windows virtual machine. +resource "azurerm_virtual_machine" "win_vm" { + count = var.is_vm_windows ? var.machine_count : 0 + name = format("%s-win-virtual-machine-%s", module.labels.id, count.index + 1) + resource_group_name = var.resource_group_name + location = var.location + network_interface_ids = [element(azurerm_network_interface.default.*.id, count.index)] + vm_size = var.vm_size + + availability_set_id = join("", azurerm_availability_set.default.*.id) + delete_os_disk_on_termination = var.delete_os_disk_on_termination + delete_data_disks_on_termination = var.delete_data_disks_on_termination + primary_network_interface_id = element(azurerm_network_interface.default.*.id, count.index) + proximity_placement_group_id = var.proximity_placement_group_id + zones = var.zones + tags = module.labels.tags + + os_profile_windows_config { + provision_vm_agent = true + } + + os_profile { + computer_name = var.computer_name + admin_username = var.admin_username + admin_password = var.admin_password + } + + dynamic "boot_diagnostics" { + for_each = var.boot_diagnostics_enabled ? [1] : [] + + content { + enabled = var.boot_diagnostics_enabled + storage_uri = var.blob_endpoint + } + } + + dynamic "additional_capabilities" { + for_each = var.addtional_capabilities_enabled ? [1] : [] + + content { + ultra_ssd_enabled = var.ultra_ssd_enabled + } + } + + dynamic "identity" { + for_each = var.identity_enabled ? [1] : [] + + content { + type = var.vm_type + identity_ids = var.identity_ids + } + } + + storage_os_disk { + create_option = var.create_option + # storage_account_type = var.os_disk_storage_account_type + caching = var.caching + # disk_encryption_set_id = var.disk_encryption_set_id + disk_size_gb = var.disk_size_gb + write_accelerator_enabled = var.enable_os_disk_write_accelerator + name = format("%s-wis-storage-data-disk", module.labels.id) + } + + dynamic "storage_image_reference" { + for_each = var.source_image_id != null ? [] : [1] + content { + publisher = var.custom_image_id != null ? var.image_publisher : "" + offer = var.custom_image_id != null ? var.image_offer : "" + sku = var.custom_image_id != null ? var.image_sku : "" + version = var.custom_image_id != null ? var.image_version : "" + } + } + + timeouts { + create = var.create + update = var.update + read = var.read + delete = var.delete + } +} + + #Module : VIRTUAL MACHINE NETWORK SECURITY GROUP ASSOCIATION #Description : Terraform resource to create a virtual machine. resource "azurerm_network_interface_security_group_association" "default" { diff --git a/variables.tf b/variables.tf index 245d944..f150373 100644 --- a/variables.tf +++ b/variables.tf @@ -449,6 +449,11 @@ variable "delete_os_disk_on_termination" { description = "Should the OS Disk (either the Managed Disk / VHD Blob) be deleted when the Virtual Machine is destroyed? Defaults to false." } +variable "enable_os_disk_write_accelerator" { + description = "Should Write Accelerator be Enabled for this OS Disk? This requires that the `storage_account_type` is set to `Premium_LRS` and that `caching` is set to `None`." + default = false +} + variable "delete_data_disks_on_termination" { type = bool default = true @@ -469,7 +474,7 @@ variable "linux_enabled" { variable "disable_password_authentication" { type = bool - default = true + default = false description = "Specifies whether password authentication should be disabled." } @@ -497,6 +502,26 @@ variable "provision_vm_agent" { description = "Should the Azure Virtual Machine Guest Agent be installed on this Virtual Machine? Defaults to false." } +variable "os_disk_storage_account_type" { + description = "The Type of Storage Account which should back this the Internal OS Disk. Possible values include Standard_LRS, StandardSSD_LRS and Premium_LRS." + default = "StandardSSD_LRS" +} + +variable "disk_encryption_set_id" { + description = "The ID of the Disk Encryption Set which should be used to Encrypt this OS Disk. The Disk Encryption Set must have the `Reader` Role Assignment scoped on the Key Vault - in addition to an Access Policy to the Key Vault" + default = null +} + +variable "additional_unattend_content" { + description = "The XML formatted content that is added to the unattend.xml file for the specified path and component." + default = null +} + +variable "additional_unattend_content_setting" { + description = "The name of the setting to which the content applies. Possible values are `AutoLogon` and `FirstLogonCommands`" + default = null +} + variable "enable_automatic_upgrades" { type = bool default = false @@ -581,18 +606,50 @@ variable "admin_username" { description = "Specifies the name of the local administrator account." } +variable "source_image_id" { + description = "The ID of an Image which each Virtual Machine should be based on" + default = null +} + variable "admin_password" { type = string default = "" description = "The password associated with the local administrator account." } +variable "windows_distribution_name" { + default = "windows2019dc" + description = "Variable to pick an OS flavour for Windows based VM. Possible values include: winserver, wincore, winsql" +} + variable "vault_enabled" { type = bool default = false description = "Whether key vault is enabled." } +variable "is_vm_windows" { + type = bool + default = false + description = "Create Windows Virtual Machine." +} + +variable "is_vm_linux" { + type = bool + default = false + description = "Create Linux Virtual Machine." +} + +variable "enable_boot_diagnostics" { + description = "Should the boot diagnostics enabled?" + default = false +} + +variable "windows_protocol" { + description = "Specifies the protocol of winrm listener. Possible values are `Http` or `Https`" + default = null +} + variable "source_vault_id" { type = string default = "" @@ -641,6 +698,12 @@ variable "caching" { description = "Specifies the caching requirements for the OS Disk. Possible values include None, ReadOnly and ReadWrite." } +variable "computer_name" { + type = string + default = "" + description = "Name of the Windows Computer Name." +} + variable "disk_size_gb" { type = number default = 8 @@ -671,6 +734,16 @@ variable "managed_disk_id" { description = "Specifies the ID of an existing Managed Disk which should be attached as the OS Disk of this Virtual Machine. If this is set then the create_option must be set to Attach." } +variable "data_disks" { + description = "Managed Data Disks for azure viratual machine" + type = list(object({ + name = string + storage_account_type = string + disk_size_gb = number + })) + default = [] +} + variable "managed_disk_type" { type = string default = ""