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

Terraform配置中NSG与Subnet关联错误排查求助

Terraform NSG与子网关联配置错误排查与修复

问题概述

配置NSG与子网关联时,执行terraform plan -var-file=dev.tfvars返回以下错误:

Error: Unsupported attribute
│ 
│   on networking_nsgs.tf line 19, in resource "azurerm_subnet_network_security_group_association" "subnet_association":
│   19:     subnet_id                 = data.azurerm_subnet.subnet_data.subnet.id
│ 
│ This object has no argument, nested block, or exported attribute named "subnet".
╵
╷
│ Error: Reference to undeclared resource
│ 
│   on networking_nsgs.tf line 20, in resource "azurerm_subnet_network_security_group_association" "subnet_association":
│   20:     network_security_group_id = azurerm_network_security_group.nsg.id
│ 
│ A managed resource "azurerm_network_security_group" "nsg" has not been declared in the root module.

现有配置代码

app1-data.tf

data "azurerm_subnet" "subnet_data" {
  name                 = var.subnet_name
  virtual_network_name = var.net_name
  resource_group_name = var.resource_group_name
}

app1-networking_nsgs.tf

module "nsg-app1" {
  source = "git@gitlab.com:*/*"
  nsg_name            = var.nsg_name
  resource_group_name = var.resource_group_name
  location            = var.location
  nsg_security_rules = var.nsg_security_rules
}


# Associate the NSG with the subnet
resource "azurerm_subnet_network_security_group_association" "subnet_association" {

  # subnet_id                 = var.subnet_id
    subnet_id                 = data.azurerm_subnet.subnet_data.subnet.id
    network_security_group_id = data.azurerm_network_security_group.nsg_data.id
  # network_security_group_id = data.azurerm_network_security_group.nsg_data[0].id
}

module-subnet-main.tf

# Create the Subnet
resource "azurerm_subnet" "subnet" {
  name                 = var.subnet_names
  resource_group_name  = var.resource_group_name
  virtual_network_name = var.vnet_name
  address_prefixes     = var.subnet_cidr_list
}

module-subnet-outputs.tf

output "subnet_name" {
  description = "Name of the created subnet"
  value       = azurerm_subnet.subnet.name
}

output "subnet_id" {
  value = azurerm_subnet.subnet.id
}

output "subnet_cidr_list" {
  value = azurerm_subnet.subnet.address_prefixes
}

module-subnet-variables.tf

variable "subnet_names" {
  type = string
}

variable "resource_group_name" {
  type        = string
  description = "name of resource group"
}

variable "subnet_cidr_list" {
  type        = list(any)
  description = "Address prefixes of Subnet"
}

variable "vnet_name" {
  type        = string
  description = "Name of Virtual Network"
}

module-nsg-main.tf

resource "azurerm_network_security_group" "nsg" {
  name                = var.nsg_name
  resource_group_name = var.resource_group_name
  location            = var.location
  # tags                = var.tags

  dynamic "security_rule" {
    for_each = var.nsg_security_rules
    content {
      name                                       = lookup(security_rule.value, "name", null)
      priority                                   = lookup(security_rule.value, "priority", null)
      direction                                  = lookup(security_rule.value, "direction", null)
      access                                     = lookup(security_rule.value, "access", null)
      protocol                                   = lookup(security_rule.value, "protocol", null)
      source_port_range                          = lookup(security_rule.value, "source_port_range", null)
      source_port_ranges                         = lookup(security_rule.value, "source_port_ranges", null)
      destination_port_range                     = lookup(security_rule.value, "destination_port_range", null)
      destination_port_ranges                    = lookup(security_rule.value, "destination_port_ranges", null)
      source_address_prefix                      = lookup(security_rule.value, "source_address_prefix", null)
      source_address_prefixes                    = lookup(security_rule.value, "source_address_prefixes", null)
      destination_address_prefix                 = lookup(security_rule.value, "destination_address_prefix", null)
      destination_address_prefixes               = lookup(security_rule.value, "destination_address_prefixes", null)
      source_application_security_group_ids      = lookup(security_rule.value, "source_application_security_group_ids ", null)
      destination_application_security_group_ids = lookup(security_rule.value, "destination_application_security_group_ids ", null)
    }
  }
}

module-nsg-outputs.tf

output "nsg_id" {
  description = "The ID of the newly created Network Security Group"
  value       = azurerm_network_security_group.nsg.id
}

output "nsg_name" {
  description = "The name of the new NSG"
  value       = azurerm_network_security_group.nsg.name
}

module-nsg-variables.tf

variable "resource_group_name" {
  description = "description"
  type        = string
}

variable "location" {
  description = "description"
  type        = string
  # default     = "West Europe"
}

variable "nsg_name" {
  description = "description"
  type        = string
}

variable "nsg_security_rules" {
  description = "A list of security rules to add to the security group. Each rule should be a map of values to add. See the Readme.md file for further details."

  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
  }))
}

错误原因与修复方案

错误1:Unsupported attribute - data.azurerm_subnet.subnet_data.subnet.id

azurerm_subnet数据源直接导出id属性,不需要额外的.subnet层级,正确引用方式:

subnet_id = data.azurerm_subnet.subnet_data.id

错误2:Reference to undeclared resource - azurerm_network_security_group.nsg.id

你已通过module "nsg-app1"调用NSG模块,需直接引用模块输出的nsg_id,而非根模块未声明的资源。同时配置中引用的data.azurerm_network_security_group.nsg_data未定义,直接使用模块输出即可:

network_security_group_id = module.nsg-app1.nsg_id

修复后的关联配置

修改app1-networking_nsgs.tf中的关联块:

resource "azurerm_subnet_network_security_group_association" "subnet_association" {
  subnet_id                 = data.azurerm_subnet.subnet_data.id
  network_security_group_id = module.nsg-app1.nsg_id
}

额外建议

如果子网是通过module-subnet模块创建的,建议直接引用该模块的subnet_id输出,保证配置一致性:

# 假设已调用子网模块
module "subnet-app1" {
  source = "./path/to/subnet-module"
  # 传入所需变量
}

# 关联时使用模块输出
resource "azurerm_subnet_network_security_group_association" "subnet_association" {
  subnet_id                 = module.subnet-app1.subnet_id
  network_security_group_id = module.nsg-app1.nsg_id
}

内容的提问来源于stack exchange,提问作者Cyborganizer

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 19:36:31