如何引用for_each创建的K8s Service模块资源配置Azure应用网关?
dynamic "backend_address_pool" {
for_each = toset(var.backends[*].name)
content {
name = "backend-pool-${backend_address_pool.value}"
ip_addresses = flatten([
for s in module.k8s_services["${backend_address_pool.value}"].kubernetes_service.internal_lb.status : [
for lb in s.load_balancer : [
for ingress in lb.ingress : ingress.ip if ingress.ip != null
]
]
])
}
}
...
}
错误信息:
╷
│ Error: Invalid index
│
│ on appgw.tf line 49, in resource "azurerm_application_gateway" "ag":
│ 49: for s in module.k8s_services["${backend_address_pool.value}"].kubernetes_service.internal_lb.status : [
│ ├────────────────
│ │ backend_address_pool.value is "application"
│ │ module.k8s_services is object with no attributes
│
│ The given key does not identify an element in this collection value.
## 解决方案 ### 1. 调整模块调用方式 使用`for_each`遍历`var.backends`实例化模块,让`module.k8s_services`成为以backend名称为键的对象集合: ```hcl module "k8s_services" { source = "./modules/k8s_services" for_each = { for b in var.backends : b.name => b } name = each.value.name k8s_namespace = each.value.k8s_namespace selector = ... # 替换为你的实际selector配置 }
2. 为模块添加输出
在modules/k8s_services目录下创建outputs.tf,显式暴露Service的状态信息(Terraform模块不会自动暴露内部资源属性):
output "service_status" { description = "Status details of the internal LoadBalancer Service" type = object({ load_balancer = object({ ingress = list(object({ ip = string })) }) }) value = kubernetes_service.internal_lb.status }
3. 修改应用网关配置
调整dynamic块的for_each逻辑,直接遍历模块实例集合,通过输出简化IP提取:
resource "azurerm_application_gateway" "ag" { ... dynamic "backend_address_pool" { for_each = module.k8s_services content { name = "backend-pool-${backend_address_pool.key}" ip_addresses = [ for ingress in backend_address_pool.value.service_status.load_balancer.ingress : ingress.ip if ingress.ip != null ] } } ... }
关键说明
- 原始错误核心是未用
for_each批量实例化模块,导致module.k8s_services不是可索引的多实例集合。 - 模块必须显式输出需要引用的属性,不能直接跨模块访问内部资源的属性。
- 简化IP提取逻辑:
service_status.load_balancer.ingress本身是列表,直接过滤非空IP即可,无需多层嵌套flatten。
内容的提问来源于stack exchange,提问作者virdz

