从模块中引用动态块

Reference a dynamic block from within a module

我不是 100% 确定如何引用嵌套在 nsg 根模块中的这个动态块。

我对 Terraform 还是很陌生,似乎无法弄明白,我在这里错过了什么?

请问有人能帮我处理我的代码吗?

错误:

Error: Missing required argument
│
│   on nsgs.tf line 1, in module "nsg-subnet1-ansible":
│    1: module "nsg-subnet1-ansible" {
│
│ The argument "network_security_group_rules" is required, but no definition was found.
╵
╷
│ Error: Unsupported argument
│
│   on nsgs.tf line 7, in module "nsg-subnet1-ansible":
│    7:   security_rule = [
│
│ An argument named "security_rule" is not expected here.

NSG 模块块

module "nsg-subnet1-ansible" {
  network_security_group_name     = var.network_security_group_name
  network_security_group_location = module.rg-networkcore.location
  resource_group_name             = module.rg-networkcore.resource_group_name

  security_rule = [
    {

      name                       = "AllowSSH"
      priority                   = 100
      direction                  = "Inbound"
      access                     = "Allow"
      protocol                   = "Tcp"
      source_port_range          = "*"
      destination_port_range     = "22"
      source_address_prefix      = "?.?.?.?"
      destination_address_prefix = "*"

    }
  ]
}

modules/nsg/main.tf

resource "azurerm_network_security_group" "nsg" {
  name                = var.network_security_group_name
  location            = var.network_security_group_location
  resource_group_name = var.resource_group_name

  dynamic "security_rule" {
    for_each = var.network_security_group_rules
    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"]
    }
  }
}

modules/nsg/outputs.tf

output "network_security_group_id" {
  value = azurerm_network_security_group.nsg.*.id
}

output "network_security_group_name" {
  value = azurerm_network_security_group.nsg.name
}

modules/nsg/variables.tf

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

variable "network_security_group_location" {
  type        = string
  description = "location of resource group"
}

variable "network_security_group_name" {
  type        = string
  description = "name of nsg group"
}

# NSG Rule Variables
variable "network_security_group_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 = "The values for each NSG rule "
}

您正在使用的 dynamic 块称为 "security_rule"。但是,为了创建该类型的块,您已将 for_each 设置为遍历名为 network_security_group_rules 的变量。这意味着当您调用模块时,您应该将 network_security_group_rules 传递给它,而不是 security_rule。将模块视为其他编程语言中的函数:您有一组传递给函数的输入变量。类似的事情也适用于此。由于您的模块具有不提供任何默认值的变量,这意味着您必须在调用模块时提供所有这些值。调用模块时的伪代码是:

module "nsg-subnet1-ansible" (resource_group_name, network_security_group_location, network_security_group_name, network_security_group_rules)

换句话说,您必须将模块调用调整为如下所示:

module "nsg-subnet1-ansible" {
  network_security_group_name     = var.network_security_group_name
  network_security_group_location = module.rg-networkcore.location
  resource_group_name             = module.rg-networkcore.resource_group_name

  network_security_group_rules = [
    {
      name                       = "AllowSSH"
      priority                   = 100
      direction                  = "Inbound"
      access                     = "Allow"
      protocol                   = "Tcp"
      source_port_range          = "*"
      destination_port_range     = "22"
      source_address_prefix      = "?.?.?.?"
      destination_address_prefix = "*"
    }
  ]
}

但是,我强烈建议在根模块中使用另一个变量,而不是 hard-coding 一个规则。例如,您可以在根模块中定义一个名为 network_security_group_rules 的变量,这可能会帮助您在将来调用该模块时避免混淆:

variable "network_security_group_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 = "Security Group rules settings."
}

该变量的值将是:

network_security_group_rules = [
    {
      name                       = "AllowSSH"
      priority                   = 100
      direction                  = "Inbound"
      access                     = "Allow"
      protocol                   = "Tcp"
      source_port_range          = "*"
      destination_port_range     = "22"
      source_address_prefix      = "?.?.?.?"
      destination_address_prefix = "*"
    }
  ]

然后,在模块调用中,您只需使用:

module "nsg-subnet1-ansible" {
  network_security_group_name     = var.network_security_group_name
  network_security_group_location = module.rg-networkcore.location
  resource_group_name             = module.rg-networkcore.resource_group_name

  network_security_group_rules = var.network_security_group_rules
}

这样,如果您以后决定添加新规则,您只需将它们添加到变量值而不是直接添加。有一些重复代码,但在您感觉足够舒服之前,这应该有所帮助。确保您了解如何在模块 [1].

中使用 Input variables

[1] https://www.terraform.io/language/modules/develop#module-structure