如何在动态块中传递多个值类型以在 Terraform 模块中创建自定义 azurerm NSG 规则?

问题描述

我创建了一个网络模块,用于创建一个 vnet、vnet 中的一组子网,然后为每个子网创建一个网络安全组。现在,我尝试在每个映射子网下的已配置 nsg_rules 列表上使用动态块 for_each 循环传入自定义 nsg 安全规则。

这主要是有效的。但是,每当安全规则需要一个不是 string 的值时,例如我定义多个非连续端口的 destination_port_ranges(它采用 list 值),模块出错:“不能在字符串模板中包含给定的值:需要字符串。”

resource "azurerm_network_security_group" "nsg" {
  for_each = var.subnets

  name                = "nsg-${each.value.subnet_name}"
  resource_group_name = azurerm_resource_group.network_rg.name
  location            = var.location
  dynamic "security_rule" {
    for_each = lookup(each.value,"nsg_rules",[])
    content {
      name                       = security_rule.value[0] == "" ? "Default_Rule" : security_rule.value[0]
      priority                   = security_rule.value[1]
      direction                  = security_rule.value[2] == "" ? "Inbound" : security_rule.value[2]
      access                     = security_rule.value[3] == "" ? "Allow" : security_rule.value[3]
      protocol                   = security_rule.value[4] == "" ? "Tcp" : security_rule.value[4]
      source_port_range          = "*"
      destination_port_ranges    = security_rule.value[5] == "" ? "*" : security_rule.value[5]
      source_address_prefix      = security_rule.value[6] == "" ? element(each.value.subnet_address_prefix,0) : security_rule.value[6]
      destination_address_prefix = security_rule.value[7] == "" ? element(each.value.subnet_address_prefix,0) : security_rule.value[7]
      description                = "${security_rule.value[2]}_Port_${security_rule.value[5]}"
    }
  }
}

以下是安全规则的根模块值:

module "network_us" {
source  = "app.terraform.io/some_workspace/network/azurerm"
version = "0.4.21"

zone_name      = var.zone_name
environment    = var.environment
location       = "eastus"
location_short = "eastus"
name_suffix    = "001"

address_space  = ["10.252.74.0/23"]
dns_servers    = []
subnets        = {
  bastion_subnet = {
    subnet_name           = "AzureBastionsubnet"
    subnet_address_prefix = ["10.252.75.64/27"]
    nsg_rules     = [
      # [name,priority,direction,access,protocol,destination_port_ranges,source_address_prefix,destination_address_prefix]
      ["AllowHttpsInbound","120","Inbound","Allow","Tcp",["443"],"Internet",""],["AllowGatewayManagerInbound","130","GatewayManager",["AllowAzureLoadBalancerInbound","140","AzureLoadBalancer",["AllowBastionHostCommunication","150","*",["8080","5701"],"VirtualNetwork","VirtualNetwork"],["AllowSshRdpOutbound","100","Outbound",["22","3389"],["AllowAzureCloudOutbound","110","AzureCloud"],["AllowBastionCommunication",["AllowGetSessioninformation",["80"],"Internet"]
    ]
  }
}

}

这是我运行申请时遇到的错误

The given value is not suitable for child module variable "subnets" defined at
.terraform/modules/network_apac/variables.tf:37,1-17: all map elements must
have the same type.

我该如何解决这个问题?

解决方法

原来问题只是在 destination_port_ranges 值的条件表达式中。它期待一个字符串并获得一个列表。我并不真的需要这些“安全网”条件,所以我只是删除了它们,模块按预期工作。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...