Terraform条件判断异常:无法仅在uat环境admin主机名时创建私有资源
问题:Terraform条件逻辑错误导致始终创建私有服务链接和DNS区域
需求:仅当hostname为admin且environment为uat时,才创建private service link和private DNS zone;其他情况不创建。但当前的条件判断始终返回true,导致资源一直被创建。
有问题的代码片段
resource "your_resource_type" "example_resource" { for_each = merge([ for i in setproduct(keys(local.static_web_app_names), keys(var.environments)) : { join("-", i) = { environment = i[1] hostname = local.static_web_app_names[i[0]] prefixes = i } } ]...) private_endpoints_subnet_resource = (each.value["environment"] != "uat" && each.value["hostname"] != "admin") || each.value["environment"] != "prod" ? local.private_endpoints_subnet_resource : null private_dns_zone_resource = (each.value["environment"] != "uat" && each.value["hostname"] != "admin") || each.value["environment"] != "prod" ? lookup(var.dns_zones_resources[each.value["environment"]][each.value["hostname"]], "private", null) : null private_dns_zones_ids = (each.value["environment"] != "uat" && each.value["hostname"] != "admin") || each.value["environment"] != "prod" ? var.private_dns_zones_ids[each.value["environment"]] : [] }
单条件可正常工作的代码(仅排除uat环境)
当仅使用单一条件each.value["environment"] != "uat"时,代码能按预期移除所有uat环境中的私有DNS和私有服务链接配置,但这不符合“仅uat+admin才创建”的需求。
resource "your_resource_type" "example_resource" { for_each = merge([ for i in setproduct(keys(local.static_web_app_names), keys(var.environments)) : { join("-", i) = { environment = i[1] hostname = local.static_web_app_names[i[0]] prefixes = i } } ]...) private_endpoints_subnet_resource = each.value["environment"] != "uat" ? local.private_endpoints_subnet_resource : null private_dns_zone_resource = each.value["environment"] != "uat" ? lookup(var.dns_zones_resources[each.value["environment"]][each.value["hostname"]], "private", null) : null private_dns_zones_ids = each.value["environment"] != "uat" ? var.private_dns_zones_ids[each.value["environment"]] : [] }
问题分析
原条件(each.value["environment"] != "uat" && each.value["hostname"] != "admin") || each.value["environment"] != "prod"逻辑错误,永远返回true:
- 如果
environment是uat,则each.value["environment"] != "prod"为true,整个表达式结果为true; - 如果
environment是prod,则each.value["environment"] != "uat"为true,结合hostname != admin(无论hostname是什么,只要env是prod,这部分都为true),整个&&表达式为true,最终||结果还是true; - 如果
environment是其他值,each.value["environment"] != "uat"和each.value["environment"] != "prod"都为true,表达式结果必然为true。
这就导致所有场景下都会赋值资源,而非仅在uat+admin的场景。
修复方案
根据需求,我们需要仅当environment为uat且hostname为admin时才设置资源值,其他情况(包括prod环境)都设为null或空数组:
resource "your_resource_type" "example_resource" { for_each = merge([ for i in setproduct(keys(local.static_web_app_names), keys(var.environments)) : { join("-", i) = { environment = i[1] hostname = local.static_web_app_names[i[0]] prefixes = i } } ]...) private_endpoints_subnet_resource = (each.value["environment"] == "uat" && each.value["hostname"] == "admin") ? local.private_endpoints_subnet_resource : null private_dns_zone_resource = (each.value["environment"] == "uat" && each.value["hostname"] == "admin") ? lookup(var.dns_zones_resources[each.value["environment"]][each.value["hostname"]], "private", null) : null private_dns_zones_ids = (each.value["environment"] == "uat" && each.value["hostname"] == "admin") ? var.private_dns_zones_ids[each.value["environment"]] : [] }
如果需要额外明确排除prod环境(虽然uat与prod互斥,此条件可省略),可调整为:
private_endpoints_subnet_resource = (each.value["environment"] == "uat" && each.value["hostname"] == "admin" && each.value["environment"] != "prod") ? local.private_endpoints_subnet_resource : null
内容的提问来源于stack exchange,提问作者Duke
相关产品推荐
相关产品推荐

