【问题标题】:Terraform NSG rules from multiple module outputs with for_each使用 for_each 来自多个模块输出的 Terraform NSG 规则
【发布时间】:2021-08-26 16:36:19
【问题描述】:

寻找一些关于我面临的以下问题的指导......

我们在 .tfvars 中定义映射,使用 for_each 引用这些映射来部署我们的模块。这已经有一段时间了……但是,我们最近部署了一个集群环境。所以,我们现在有两个应用服务器,在 .tfvars 中定义:

tfvars 中的 app_servers 映射:

app_servers = {
  sr-app-1 = {
    size             = "Standard_E2s_v3"
    admin_username   = "azureuser"
    data_disks       = [64]
    zone_vm          = "1"
    zone_disk        = ["1"]
    os_disk_size     = 64
    web_server       = "sr-web-1"
  },
  sr-app-2 = {
    size             = "Standard_E2s_v3"
    admin_username   = "azureuser"
    data_disks       = [64]
    zone_vm          = "1"
    zone_disk        = ["1"]
    os_disk_size     = 64
    web_server       = "sr-web-2"
  }
}

tfvars 中的 db_servers 映射

db_servers = {
  sr-fdb-1 = {
    size             = "Standard_D4s_v3"
    admin_user       = "azureuser"
    data_disks       = [64, 64, 128]
    zone_vm          = "1"
    zone_disk        = ["1"]
    os_disk_size     = 128
    app_server       = "sr-app-1"
    etl_server       = "sr-etl-1"
  }
  sr-sdb-1 = {
    size             = "Standard_D4s_v3"
    admin_user       = "azureuser"
    data_disks       = [64, 64, 128]
    zone_vm          = "1"
    zone_disk        = ["1"]
    os_disk_size     = 128
    app_server       = "sr-app-1"
    etl_server       = "sr-etl-1"
  }
}

我们正在使用来自底层 linux_vm 模块的outputs.tf 为我们的 NSG 规则(模块外部,main.tf)填充source_address_prefixes。因为我们在db_servers 映射(如下)上使用for_each,所以我们无法访问app_servers 映射。因此,我们在db_servers 映射中添加了一个键,以识别为每个app_servers 运行的特定模块,(见上文db_servers 映射):

outputs.tf(在 linux_vm 模块内):

output "linux_vm_ip" {
  value = azurerm_network_interface.uks_network_interface.private_ip_address
}

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

main.tf:

module "fico_db_vm" {
  for_each                = var.db_servers
  source                  = "../modules/compute/windows_vm"
  source_image_id         = var.db_image_id
  vm_name                 = each.key
  vm                      = each.value
  subnet_name             = "back-end-01"
  resource_group          = azurerm_resource_group.rg_uks_fico_db.name
  data_disks              = each.value["data_disks"]
  enable_management_locks = true
}
resource "azurerm_network_security_rule" "fico-db-sr-1433" {
  for_each                    = var.db_servers
  name                        = "nsr-${var.location}-${var.environment}-${var.directorate}-${var.business_unit}-sql"
  priority                    = 100
  direction                   = "Inbound"
  access                      = "Allow"
  protocol                    = "*"
  source_port_range           = "*"
  destination_port_range      = "1433"
  source_address_prefixes     = [module.fico_app_vm[each.value.app_server].linux_vm_ip, module.fico_etl_vm[each.value.etl_server].windows_vm_ip]
  destination_address_prefix  = "VirtualNetwork"
  resource_group_name         = azurerm_resource_group.rg_uks_fico_db.name
  network_security_group_name = module.fico_db_vm[each.key].windows_vm_nsg
}

这在我们都是单实例的 SBOX/DEV 环境中运行良好 - 但是,我们现在已将集群应用程序部署到我们的 TEST 环境中。我想不出一种将辅助应用服务器 IP 添加到上述 NSG 规则的好方法。

最初我尝试将新键 (app_server2) 添加到 db_servers 映射,以便可以以相同的方式引用: source_address_prefixes = [module.fico_app_vm[each.value.app_server].linux_vm_ip, module.fico_app_vm[each.value.app_server2].linux_vm_ip, module.fico_etl_vm[each.value.etl_server].windows_vm_ip]

它在 TEST 中按预期工作,但这不可行,因为 Terraform 计划在我们现有的 SBOX/DEV 环境中运行相同的代码时抱怨 app_server2 未定义...

我已尝试将 app_server2 添加到 SBOX/DEV tfvar 中作为“null”或只是一个空值,但这也有抱怨,因为似乎地图不能为空/null?

也许我离兔子洞太远了,看不到明显的解决方案,任何建议/指导将不胜感激。

【问题讨论】:

  • 你能澄清一下吗?您写道[module.fico_app_vm[each.value.app_server].linux_vm_ip, module.fico_etl_vm[each.value.etl_server].windows_vm_ip] 适合 SBOX/DEV 环境。但不在 TEST 中?那么它在 TEST 中不起作用是什么意思呢?理想情况下,这个列表应该是什么?有没有错误?
  • 作为一种解决方法,您添加了app_server2?它看起来怎么样?

标签: azure module terraform


【解决方案1】:

我最终通过在我的地图中删除对其他地图的引用来解决这个特殊问题...

相反,我在 main.tf 中添加了一些局部变量

locals {
  app_vm_ips = [
    for key, val in module.fico_app_vm :
    module.fico_app_vm[key].linux_vm_ip
  ]
  web_vm_ips = [
    for key, val in module.fico_web_vm :
    module.fico_web_vm[key].linux_vm_ip
  ]
  etl_vm_ips = [
    for key, val in module.fico_etl_vm :
    module.fico_etl_vm[key].windows_vm_ip
  ]
}

然后我在azurerm_network_security_group_rule 资源中使用了这些局部变量,如下所示:

resource "azurerm_network_security_rule" "fico-db-sr-1433" {
  for_each                    = var.db_servers
  name                        = "nsr-${var.location}-${var.environment}-${var.directorate}-${var.business_unit}-sql"
  priority                    = 100
  direction                   = "Inbound"
  access                      = "Allow"
  protocol                    = "*"
  source_port_range           = "*"
  destination_port_range      = "1433"
  source_address_prefixes     = concat(local.app_vm_ips, local.etl_vm_ips)
  destination_address_prefix  = "VirtualNetwork"
  resource_group_name         = azurerm_resource_group.rg_uks_fico_db.name
  network_security_group_name = module.fico_db_vm[each.key].windows_vm_nsg
}

【讨论】:

    猜你喜欢
    • 2021-03-07
    • 2021-03-21
    • 1970-01-01
    • 2021-03-31
    • 1970-01-01
    • 2021-07-09
    • 2021-09-24
    • 2021-04-14
    • 2021-08-16
    相关资源
    最近更新 更多