You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Terraform Azure中为通过for_each循环创建的不同网络安全组分配专属安全规则

没问题,我来帮你调整Terraform配置,实现每个NSG只绑定专属的安全规则。核心思路是把NSG标识和对应的规则列表做关联,然后在创建NSG时过滤出它需要的规则就行。具体修改步骤如下:

1. 调整变量结构,统一管理NSG与规则的映射

首先把原来分散的三个规则名称列表,合并成一个映射变量,这样能清晰看到每个NSG对应哪些规则。修改variables.tf:

# 替换原来的db_nsg_rules、dataanalysis_nsg_rules、dataengineering_nsg_rules变量
variable "nsg_rule_assignments" {
  type = map(list(string))
  description = "映射NSG名称(对应var.vm_names里的值)到它需要的规则名称列表"
  default = {
    "db"                = ["allow-ssh", "allow-http-all", "allow-https-all", "allow-ping", "allow-postgreSql-traffic", "allow-pgadmin-traffic"]
    "dataanalysis"      = ["allow-ssh", "allow-http-all", "allow-https-all", "allow-ping", "allow-2223-traffic", "allow-80-89-traffic", "allow-90-99-traffic", "allow-5601-traffic", "allow-3000-traffic"]
    "dataengineering"   = ["allow-ssh", "allow-http-all", "allow-https-all", "allow-ping", "allow-superset-traffic", "allow-kafka1-traffic", "allow-kafka2-traffic", "allow-kafka3-traffic", "allow-kafka4-traffic", "allow-kafka5-traffic"]
  }

  # 可选:加个校验,确保var.vm_names里的每个NSG都有对应的规则分配
  validation {
    condition     = alltrue([for name in var.vm_names : contains(keys(var.nsg_rule_assignments), name)])
    error_message = "var.vm_names里的所有NSG名称,必须在nsg_rule_assignments里有对应条目。"
  }
}

# 保留原来的nsg_rules变量,不用修改
variable "nsg_rules" {
  type = list(object({
    name                       = string
    priority                   = number
    direction                  = string
    access                     = string
    protocol                   = string
    source_port_range          = string
    destination_port_range     = string
    source_address_prefix      = string
    destination_address_prefix = string
  }))
  description = "所有NSG规则的详细定义"
}

2. 修改NSG资源,过滤专属规则

接下来修改main.tf里的dynamic "security_rule"块,通过列表推导式从全局规则中筛选出当前NSG需要的规则:

resource "azurerm_network_security_group" "nsg" {
  for_each             = toset(var.vm_names)
  name                 = "${each.value}-nsg"
  location             = var.location
  resource_group_name  = azurerm_resource_group.rg.name

  dynamic "security_rule" {
    # 核心:只保留当前NSG分配列表里的规则
    for_each = [
      rule for rule in var.nsg_rules 
      if contains(var.nsg_rule_assignments[each.value], rule.name)
    ]
    content {
      name                       = security_rule.value.name
      priority                   = security_rule.value.priority
      direction                  = security_rule.value.direction
      access                     = security_rule.value.access
      protocol                   = security_rule.value.protocol
      source_port_range          = security_rule.value.source_port_range
      destination_port_range     = security_rule.value.destination_port_range
      source_address_prefix      = security_rule.value.source_address_prefix
      destination_address_prefix = security_rule.value.destination_address_prefix
    }
  }
}

逻辑说明

  • nsg_rule_assignments是一个键值对,键是你的NSG标识(比如db),值是该NSG需要启用的规则名称列表,后续要调整规则分配时,直接修改这个映射就行,非常直观。
  • 在dynamic块的for_each里,我们用列表推导式遍历全局规则var.nsg_rules,只保留名称在当前NSG分配列表中的规则,这样每个NSG只会绑定自己专属的规则。
  • 可选的变量校验能提前发现配置错误,避免因为NSG名称和映射不匹配导致的部署失败。

内容的提问来源于stack exchange,提问作者Karin88-mich

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 00:59:07