Terraform 希望部署子网但禁用网络安全组

Terraform looking to deploy subnet but disable the network security group

我理解下面的错误,但不确定如何创建我正在寻找的逻辑。

我希望使用计数参数关闭网络安全组,但仍想创建子网。

如何实现,禁用网络安全组但仍然创建子网。

//link to code
https://github.com/Azure-Terraform/terraform-azurerm-virtual-network

//what I tried this far for: resource "azurerm_subnet" "subnet"
var.enable_nsg && length(var.subnets) > 0 ? length(var.subnets) : 0

//result:
throws error below.
Error: Error in function call

  on ..\terraform-azurerm-virtual-network-master\vnet\output.tf line 24, in output "subnet_nsg_names":
  24:   value       =  zipmap(
  25:     [for subnet in azurerm_subnet.subnet: subnet.name],
  26:     [for nsg in azurerm_network_security_group.nsg: nsg.name]
  27:   )
    |----------------
    | azurerm_network_security_group.nsg is empty tuple
    | azurerm_subnet.subnet is tuple with 3 elements

Call to function "zipmap" failed: number of keys (3) does not match number of
values (0).

main.tf

resource "azurerm_virtual_network" "vnet" {
  name                = "${var.names.product_group}-${var.names.subscription_type}-${var.names.location}-vnet"
  location            = var.location
  resource_group_name = var.resource_group_name
  address_space       = var.address_space
  tags                = var.tags
}

resource "azurerm_subnet" "subnet" {
  count                = length(var.subnets)
  name                 = "${substr(keys(var.subnets)[count.index], 3, -1)}-subnet"
  resource_group_name  = var.resource_group_name
  virtual_network_name = azurerm_virtual_network.vnet.name
  address_prefixes     = values(var.subnets)[count.index]
}

resource "azurerm_subnet_network_security_group_association" "subnet_nsg" {
  count                     = var.enable_nsg && length(var.subnets) > 0 ? length(var.subnets) : 0
  subnet_id                 = azurerm_subnet.subnet.*.id[count.index]
  network_security_group_id = azurerm_network_security_group.nsg.*.id[count.index]
}

resource "azurerm_network_security_group" "nsg" {
  count               = var.enable_nsg && length(var.subnets) > 0 ? length(var.subnets) : 0
  name                = "${var.names.resource_group_type}-${var.names.product_name}-${substr(keys(var.subnets)[count.index], 3, -1)}-security-group"
  location            = var.location
  resource_group_name = var.resource_group_name
  tags                = merge(var.tags, {subnet_type = lookup(local.subnet_types,substr(keys(var.subnets)[count.index], 3, -1))})
}

resource "azurerm_network_security_rule" "deny_all_inbound" {
  count                       = var.enable_nsg && length(var.subnets) > 0 ? length(var.subnets) : 0
  name                        = "DenyAllInbound"
  priority                    = 4096
  direction                   = "Inbound"
  access                      = "Deny"
  protocol                    = "*"
  source_port_range           = "*"
  destination_port_range      = "*"
  source_address_prefix       = "*"
  destination_address_prefix  = "*"
  resource_group_name         = var.resource_group_name
  network_security_group_name = azurerm_network_security_group.nsg.*.name[count.index]
}

resource "azurerm_network_security_rule" "deny_all_outbound" {
  count                       = var.enable_nsg && length(var.subnets) > 0 ? length(var.subnets) : 0
  name                        = "DenyAllOutbound"
  priority                    = 4096
  direction                   = "Outbound"
  access                      = "Deny"
  protocol                    = "*"
  source_port_range           = "*"
  destination_port_range      = "*"
  source_address_prefix       = "*"
  destination_address_prefix  = "*"
  resource_group_name         = var.resource_group_name
  network_security_group_name = azurerm_network_security_group.nsg.*.name[count.index]
}

variables.tf

variable "naming_rules" {
  description = "naming conventions yaml file" 
  type        = string
}

variable "resource_group_name"{
  description = "Resource group name"
  type        = string
}

variable "location" {
  description = "Azure Region"
  type        = string
}

variable "names" {
  description = "Names to be applied to resources"
  type        = map(string)
}

variable "tags" {
  description = "Tags to be applied to resources"
  type        = map(string)
}

# Networking
variable "address_space" {
  description = "CIDRs for virtual network"
  type        = list(string)
}

variable "subnets" {
  description = "Subnet types and lists of CIDRs. format: { [0-9][0-9]-<subnet_type> = cidr }) (increment from 01, cannot be reordered)"
  type        = map(list(string))
  default     = {}
}

variable "enable_nsg" {
  description = "Toggle on/off the use of a network security group. This well need to be turned off for a private link endpoint"
  type        = bool
  default     = true
}

output.tf

output "vnet" {
  description  = "Virtual network resource"
  value        = azurerm_virtual_network.vnet
}

output "subnet" {
  description = "Map of subnet resources"
  value       = zipmap(
    [for subnet in azurerm_subnet.subnet: subnet.name],
    [for subnet in azurerm_subnet.subnet: subnet]
  )
}

output "subnet_nsg_ids" {
  description = "Map of subnet ids to associated network_security_group ids"
  value       =  zipmap(
    [for subnet in azurerm_subnet.subnet: subnet.id],
    [for nsg in azurerm_network_security_group.nsg: nsg.id]
  )
}

output "subnet_nsg_names" {
  description = "Map of subnet names to associated network_security_group names"
  value       =  zipmap(
    [for subnet in azurerm_subnet.subnet: subnet.name],
    [for nsg in azurerm_network_security_group.nsg: nsg.name]
  )
}

对于错误信息,由于你使用的是zipmap函数,当NSG为空时,它不会映射子网数,你可以像这样在输出中添加条件表达式,

output "subnet_nsg_ids" {
  description = "Map of subnet ids to associated network_security_group ids"
  value       =  var.enable_nsg && length(var.subnets) > 0 ? zipmap(
    [for subnet in azurerm_subnet.subnet: subnet.id],
    [for nsg in azurerm_network_security_group.nsg: nsg.id]
  ): null
}

output "subnet_nsg_names" {
  description = "Map of subnet names to associated network_security_group names"
  value       =  var.enable_nsg && length(var.subnets) > 0 ? zipmap(
    [for subnet in azurerm_subnet.subnet: subnet.name],
    [for nsg in azurerm_network_security_group.nsg: nsg.name]
  ): null
}

所以当var.enable_nsg = false时,不会出现错误信息。