使用 for_each 创建模块时传递模块的输出

Passing the outputs from a module when the module is created using a for_each

这是我上一个问题的 link,单击 link 查看我的其余代码以及它们如何组合在一起:

虽然答案有助于解决问题并允许我 运行 管道,但我认为存在错误,因为使用模块上的 for_each 生成 VM 的方式.这会导致传递给 network_security_rule 的值不正确。以下是错误示例:

Error: Error Creating/Updating Network Security Rule "nsr-sbox-http80" (NSG "module.fico_app_vm.linux_vm_nsg" / Resource Group "rg-sbox-app"): network.SecurityRulesClient#CreateOrUpdate: Failure sending request: StatusCode=404 -- Original Error: Code="ResourceNotFound" Message="The Resource 'Microsoft.Network/networkSecurityGroups/module.fico_app_vm.linux_vm_nsg' under resource group 'rg-sbox-app' was not found. For more details please go to https://aka.ms/ARMResourceNotFoundFix"

  on main.tf line 58, in resource "azurerm_network_security_rule" "fico-app-sr-80":
  58: resource "azurerm_network_security_rule" "fico-app-sr-80" {

outputs.tf

output "linux_vm_ips" {
  value = azurerm_network_interface.dwp_network_interface.private_ip_address
}

output "linux_vm_nsg" {
  value = azurerm_network_security_group.dwp_network_security_group.name
}

起初我以为是因为没有创建 NSG,但我检查了控制台,它确实创建了它。问题是 NSG 是在每个 VM 的模块中创建的。 VM 是通过遍历 tfvars 文件中的变量创建的。如何将模块中创建的 NSG 名称传递给模块外的安全规则?:

resource "azurerm_network_security_rule" "fico-app-sr-80" {
  name                        = "nsr-${var.environment}-${var.directorate}-${var.business_unit}-${var.vm_identifier}${var.instance_number}-http80"
  priority                    = 100
  direction                   = "Inbound"
  access                      = "Allow"
  protocol                    = "*"
  source_port_range           = "*"
  destination_port_range      = "80"
  source_address_prefixes     = ["module.fico_web_vm.linux_vm_ips"]
  destination_address_prefix  = "VirtualNetwork"
  resource_group_name         = azurerm_resource_group.rg_fico_app.name
  network_security_group_name = "module.fico_app_vm.linux_vm_nsg"
}
# Network Security Group
resource "azurerm_network_security_group" "network_security_group" {
  name                = "nsg-${var.environment}-${var.directorate}-${var.business_unit}-${var.vm_identifier}-${var.vm_name}"
  resource_group_name = var.resource_group
  location            = var.location
}

还有一点需要注意,var.vm_name 遍历每个映射的键,这构成了 NSG 名称的一部分。

main.tf 中的模块:

module "fico_app_vm" {
  for_each                     = var.app_servers
  source                       = "../modules/compute/linux_vm"
  source_image_id              = var.app_image_id
  location                     = var.location
  vm_name                      = each.key
  vm_identifier                = "${var.vm_identifier}${var.instance_number}"
  vm                           = each.value
  disks                        = each.value["disks"]
  resource_group               = azurerm_resource_group.rg_fico_app.name
  directorate                  = var.directorate
  business_unit                = var.business_unit
  environment                  = var.environment
  network_rg_identifier        = var.network_rg_identifier
  subnet_name                  = "sub-${var.environment}-${var.directorate}-${var.business_unit}-be01"
  diag_storage_account_name    = var.diag_storage_account_name
  ansible_storage_account_name = var.ansible_storage_account_name
  ansible_storage_account_key  = var.ansible_storage_account_key
  log_analytics_workspace_name = var.log_analytics_workspace_name
  backup_policy_name           = var.backup_policy_name
  enable_management_locks      = true
}

tfvars:

app_servers ={
  app-1 = {
    size           = "Standard_E2s_v3"
    admin_username = "xxx"
    public_key     = "xxx"
    disks          = [32, 32]
    zone_vm        = "1"
    zone_disk      = ["1"]
  }
}

我觉得是你没有仔细看之前的回答的问题。答案显示您需要像这样更改安全组名称:

network_security_group_name = module.fico_app_vm.linux_vm_nsg

没有双引号。双引号表示它是一个字符串。但是您需要使用模块属性,而不是具有值 "module.fico_app_vm.linux_vm_nsg" 的字符串。报错也直接显示了。

我意识到我的错误是什么。我需要改变这个:

network_security_group_name = "module.fico_app_vm.linux_vm_nsg"

至此

network_security_group_name = module.fico_app_vm[each.key].linux_vm_nsg

但我还需要引用源地址前缀中的值。因此,为了引用密钥,我创建了另一个变量并更改了它:

source_address_prefixes     = ["module.fico_web_vm.linux_vm_ips"]

对此:

source_address_prefix       = module.fico_web_vm[each.value.web_server].linux_vm_ip

我还必须更改为 source_address_prefix,这就是出现类型错误的原因!

安全规则现在如下所示:

resource "azurerm_network_security_rule" "fico-app-sr-80" {
  for_each                    = var.app_servers
  name                        = "nsr-${var.environment}-${var.directorate}-${var.business_unit}-${var.vm_identifier}${var.instance_number}-http80"
  priority                    = 100
  direction                   = "Inbound"
  access                      = "Allow"
  protocol                    = "*"
  source_port_range           = "*"
  destination_port_range      = "80"
  source_address_prefix       = module.fico_web_vm[each.value.web_server].linux_vm_ip
  destination_address_prefix  = "VirtualNetwork"
  resource_group_name         = azurerm_resource_group.rg_dwp_fico_app.name
  network_security_group_name = module.fico_app_vm[each.key].linux_vm_nsg

变量看起来像这样:

app_servers = {
  app-1 = {
    size           = "Standard_E2s_v3"
    admin_username = "azureuser"
    public_key     = xxxx
    disks          = [32, 32]
    zone_vm        = "1"
    zone_disk      = ["1"]
    web_server     = "web-1"
  }
}