From fe7a357fc6c672bf98fdf22ea28008405c3cbd43 Mon Sep 17 00:00:00 2001 From: zjhe Date: Fri, 25 Nov 2022 23:18:09 +0800 Subject: [PATCH] add support for network security group injection --- README.md | 3 ++- examples/complete/main.tf | 24 ++++++++++++++++++++++++ examples/complete/outputs.tf | 32 ++++++++++++++++++++++++++++++++ main.tf | 17 ++++++++++++++--- outputs.tf | 6 +++--- variables.tf | 12 ++++++++++++ 6 files changed, 87 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index b1ee895..6ce48ff 100644 --- a/README.md +++ b/README.md @@ -432,6 +432,7 @@ Originally created by [David Tesar](http://github.com/dtzar) | [nb\_data\_disk](#input\_nb\_data\_disk) | (Optional) Number of the data disks attached to each virtual machine. | `number` | `0` | no | | [nb\_instances](#input\_nb\_instances) | Specify the number of vm instances. | `number` | `1` | no | | [nb\_public\_ip](#input\_nb\_public\_ip) | Number of public IPs to assign corresponding to one IP per vm. Set to 0 to not assign any public IP addresses. | `number` | `1` | no | +| [network\_security\_group](#input\_network\_security\_group) | The network security group we'd like to bind with virtual machine. Set this variable will disable the creation of `azurerm_network_security_group` and `azurerm_network_security_rule` resources. |
object({
id = string
})
| `null` | no | | [os\_profile\_secrets](#input\_os\_profile\_secrets) | Specifies a list of certificates to be installed on the VM, each list item is a map with the keys source\_vault\_id, certificate\_url and certificate\_store. | `list(map(string))` | `[]` | no | | [public\_ip\_dns](#input\_public\_ip\_dns) | Optional globally unique per datacenter region domain name label to apply to each public ip address. e.g. thisvar.varlocation.cloudapp.azure.com where you specify only thisvar here. This is an array of names which will pair up sequentially to the number of public ips defined in var.nb\_public\_ip. One name or empty string is required for every public ip. If no public ip is desired, then set this to an array with a single empty string. | `list(string)` |
[
null
]
| no | | [public\_ip\_sku](#input\_public\_ip\_sku) | Defines the SKU of the Public IP. Accepted values are Basic and Standard. Defaults to Basic. | `string` | `"Basic"` | no | @@ -462,7 +463,7 @@ Originally created by [David Tesar](http://github.com/dtzar) | [network\_interface\_ids](#output\_network\_interface\_ids) | ids of the vm nics provisoned. | | [network\_interface\_private\_ip](#output\_network\_interface\_private\_ip) | private ip addresses of the vm nics | | [network\_security\_group\_id](#output\_network\_security\_group\_id) | id of the security group provisioned | -| [network\_security\_group\_name](#output\_network\_security\_group\_name) | name of the security group provisioned | +| [network\_security\_group\_name](#output\_network\_security\_group\_name) | name of the security group provisioned, empty if no security group was created. | | [public\_ip\_address](#output\_public\_ip\_address) | The actual ip address allocated for the resource. | | [public\_ip\_dns\_name](#output\_public\_ip\_dns\_name) | fqdn to connect to the first vm provisioned. | | [public\_ip\_id](#output\_public\_ip\_id) | id of the public ip address provisoned. | diff --git a/examples/complete/main.tf b/examples/complete/main.tf index ae10eda..237f7d5 100644 --- a/examples/complete/main.tf +++ b/examples/complete/main.tf @@ -113,6 +113,27 @@ module "debianservers" { ] } +resource "azurerm_network_security_group" "external_nsg" { + location = var.location_alt + name = "${azurerm_resource_group.test.name}-nsg" + resource_group_name = azurerm_resource_group.test.name +} + +resource "azurerm_network_security_rule" "vm" { + access = "Allow" + direction = "Inbound" + name = "allow_remote_in_all" + network_security_group_name = azurerm_network_security_group.external_nsg.name + priority = 101 + protocol = "Tcp" + resource_group_name = azurerm_resource_group.test.name + description = "Allow remote protocol in from all locations" + destination_address_prefix = "*" + destination_port_range = "22" + source_address_prefix = "${local.public_ip}/32" + source_port_range = "*" +} + module "debianservers2" { source = "../.." vm_hostname = "${random_id.ip_dns.hex}-d2" @@ -130,6 +151,9 @@ module "debianservers2" { public_ip_sku = "Standard" ssh_key = "" ssh_key_values = [file("${path.module}/monica_id_rsa.pub")] + network_security_group = { + id = azurerm_network_security_group.external_nsg.id + } # To test `var.zone` please uncomment the line below. # zone = "2" } diff --git a/examples/complete/outputs.tf b/examples/complete/outputs.tf index 0ba5d78..1e59d41 100644 --- a/examples/complete/outputs.tf +++ b/examples/complete/outputs.tf @@ -2,6 +2,14 @@ output "debian2_availability_set_id" { value = module.debianservers2.availability_set_id } +output "debian2_nsg_id" { + value = module.debianservers2.network_security_group_id +} + +output "debian2_nsg_name" { + value = module.debianservers2.network_security_group_name +} + output "debian2_vm_names" { value = module.debianservers2.vm_names } @@ -14,6 +22,14 @@ output "debian_ip_address" { value = module.debianservers.public_ip_address } +output "debian_nsg_id" { + value = module.debianservers.network_security_group_id +} + +output "debian_nsg_name" { + value = module.debianservers.network_security_group_name +} + output "debian_vm_names" { value = module.debianservers.vm_names } @@ -52,6 +68,14 @@ output "ubuntu_ip_address" { value = module.ubuntuservers.public_ip_address } +output "ubuntu_nsg_id" { + value = module.ubuntuservers.network_security_group_id +} + +output "ubuntu_nsg_name" { + value = module.ubuntuservers.network_security_group_name +} + output "ubuntu_vm_names" { value = module.ubuntuservers.vm_names } @@ -99,6 +123,14 @@ output "windows_ip_address" { value = module.windowsservers.public_ip_address } +output "windows_nsg_id" { + value = module.windowsservers.network_security_group_id +} + +output "windows_nsg_name" { + value = module.windowsservers.network_security_group_name +} + output "windows_vm_admin_password" { sensitive = true value = local.admin_password diff --git a/main.tf b/main.tf index 002ec94..4e37494 100644 --- a/main.tf +++ b/main.tf @@ -287,20 +287,31 @@ data "azurerm_public_ip" "vm" { depends_on = [azurerm_virtual_machine.vm_linux, azurerm_virtual_machine.vm_windows] } +moved { + from = azurerm_network_security_group.vm + to = azurerm_network_security_group.vm[0] +} + resource "azurerm_network_security_group" "vm" { + count = var.network_security_group == null ? 1 : 0 + location = local.location name = "${var.vm_hostname}-nsg" resource_group_name = var.resource_group_name tags = var.tags } +locals { + network_security_group_id = var.network_security_group == null ? azurerm_network_security_group.vm[0].id : var.network_security_group.id +} + resource "azurerm_network_security_rule" "vm" { - count = var.remote_port != "" ? 1 : 0 + count = var.network_security_group == null && var.remote_port != "" ? 1 : 0 access = "Allow" direction = "Inbound" name = "allow_remote_${coalesce(var.remote_port, module.os.calculated_remote_port)}_in_all" - network_security_group_name = azurerm_network_security_group.vm.name + network_security_group_name = azurerm_network_security_group.vm[0].name priority = 101 protocol = "Tcp" resource_group_name = var.resource_group_name @@ -332,5 +343,5 @@ resource "azurerm_network_interface_security_group_association" "test" { count = var.nb_instances network_interface_id = azurerm_network_interface.vm[count.index].id - network_security_group_id = azurerm_network_security_group.vm.id + network_security_group_id = local.network_security_group_id } diff --git a/outputs.tf b/outputs.tf index ccae3f4..3d7d1e4 100644 --- a/outputs.tf +++ b/outputs.tf @@ -15,12 +15,12 @@ output "network_interface_private_ip" { output "network_security_group_id" { description = "id of the security group provisioned" - value = azurerm_network_security_group.vm.id + value = local.network_security_group_id } output "network_security_group_name" { - description = "name of the security group provisioned" - value = azurerm_network_security_group.vm.name + description = "name of the security group provisioned, empty if no security group was created." + value = join("", concat(azurerm_network_security_group.vm[*].name, [""])) } output "public_ip_address" { diff --git a/variables.tf b/variables.tf index 4452590..ed5ad7d 100644 --- a/variables.tf +++ b/variables.tf @@ -157,6 +157,18 @@ variable "nb_public_ip" { default = 1 } +variable "network_security_group" { + description = "The network security group we'd like to bind with virtual machine. Set this variable will disable the creation of `azurerm_network_security_group` and `azurerm_network_security_rule` resources." + type = object({ + id = string + }) + default = null + validation { + condition = var.network_security_group == null ? true : var.network_security_group.id != null + error_message = "When `var.network_security_group` is not `null`, `var.network_security_group.id` is required." + } +} + variable "os_profile_secrets" { description = "Specifies a list of certificates to be installed on the VM, each list item is a map with the keys source_vault_id, certificate_url and certificate_store." type = list(map(string))