Terraform遍历数据源为Azure容器注册表配置IP规则故障排查
问题
需要遍历获取VM公网IP的数据源结果,将这些IP添加到Azure容器注册表(ACR)的IP规则中。数据源本身工作正常,但使用for_each遍历并添加IP规则时失败,尝试了两种写法均无效。
现有代码
variable "vmips" { type = map(any) default = { "vm1" = "rg1", "vm2" = "rg2" } } data "azurerm_public_ip" "vmips" { for_each = var.vmips name = each.key resource_group_name = each.value } resource "azurerm_container_registry" "acr" { name = "MyAcR" resource_group_name = "myrg" location = "uksouth" sku = "Premium" admin_enabled = false public_network_access_enabled = false network_rule_set { default_action = "Deny" ip_rule { for_each = var.vmips action = "Allow" ip_range = data.azurerm_public_ip.vmips[each.key].ip_address } # or dynamic "ip_rule" { for_each = var.vmips content { action = "Allow" ip_range = data.azurerm_public_ip.vmips[each.key].ip_address } } } }
解决方法
1. 修正Dynamic块的迭代变量引用
Terraform的dynamic块中,迭代变量是你定义的块名(这里是ip_rule),而非each,所以要把each.key改成ip_rule.key。同时直接遍历数据源结果会更直观,避免依赖变量的间接引用。
2. 修复公网访问配置
如果public_network_access_enabled = false,ACR会完全禁用公网访问,此时IP规则不会生效。需要将其设置为true,配合default_action = "Deny"实现仅允许指定IP访问的效果。
修正后的代码
variable "vmips" { type = map(any) default = { "vm1" = "rg1", "vm2" = "rg2" } } data "azurerm_public_ip" "vmips" { for_each = var.vmips name = each.key resource_group_name = each.value } resource "azurerm_container_registry" "acr" { name = "MyAcR" resource_group_name = "myrg" location = "uksouth" sku = "Premium" admin_enabled = false public_network_access_enabled = true # 改为true,否则IP规则不生效 network_rule_set { default_action = "Deny" dynamic "ip_rule" { for_each = data.azurerm_public_ip.vmips content { action = "Allow" ip_range = ip_rule.value.ip_address } } } }
关键注意点
- 嵌套块不能直接使用
for_each,必须通过dynamic块实现循环创建。 dynamic块内部要使用定义的迭代变量名(如ip_rule)访问元素,而非全局的each。public_network_access_enabled必须设为true,否则ACR完全关闭公网访问,IP规则无法生效。
内容的提问来源于stack exchange,提问作者Guy Wood
相关产品推荐
相关产品推荐

