Terraform部署Azure应用网关嵌套Dynamic Blocks报错求助
解决Terraform部署Azure应用网关嵌套Dynamic Blocks验证错误
问题描述
尝试使用Terraform部署Azure应用网关,核心需求是配置嵌套的dynamic blocks来生成url_path_map和path_rule结构。已编写application_gateway.tf实现嵌套逻辑、variables.tf定义变量结构、main.tf完成模块调用,但执行terraform validate时报错,需要修正代码以生成目标配置结构。
原代码展示
application_gateway.tf
dynamic "url_path_map" { for_each = var.path_maps content { name = outer_block.value["name"] default_backend_address_pool_name = outer_block.value["backend"] default_backend_http_settings_name = outer_block.value["backend_set"] dynamic "url_path_rule" { for_each = url_path_map.value["upm"] content{ name = url_path_rule.value["name_rule"] paths = url_path_rule.value["path"] backend_address_pool_name = url_path_rule.value["backend"] backend_http_settings_name = url_path_rule.value["backend_set"] } } } }
variables.tf
variable "path_maps" { default = [] type = list(object({ name = string backend = string backend_set = string upm = list(object({ name_rule = string path = string backend = string backend_set = string })) })) }
main.tf 模块调用
module "application_gateway" { source = "../modules/resources-hub/application_gateway" resource_group_name = module.resource_group.name resource_group_location = module.resource_group.location subnet_id = module.agw_subnet.id public_ip_address_id = module.app_gw_pip.id firewall_policy_id = module.agw_web_application_firewall.id log_analytics_workspace_id = module.log_analytics_workspace.id path_maps = [{name = "dev_url_path_name", backend = "devBackend", backend_set = "devHttpSetting", name_rule = "dev_path_rule_name_app", path = "/app/*"}, {name = "tst_url_path_name", backend = "tstBackend", backend_set = "tstHttpSetting", name_rule = "dev_path_rule_name_edp", path = "/edp/*"}, {name = "uat_url_path_name", backend = "uatBackend", backend_set = "uatHttpSetting", name_rule = "dev_path_rule_name_internal", path = "/internal/*"}] }
期望生成的配置结构
url_path_map { name = "dev_url_path_name" default_backend_address_pool_name = "devBackend" default_backend_http_settings_name = "devHttpSetting" path_rule { name = "dev_path_rule_name_app_edp" paths = ["/app/*"] backend_address_pool_name = "devBackend" backend_http_settings_name = "devHttpSetting" } path_rule { name = "dev_path_rule_name_internal" paths = ["/edp/*"] backend_address_pool_name = "devBackend" backend_http_settings_name = "devHttpSetting" } path_rule { name = "dev_path_rule_name_internal" paths = ["/internal/*"] backend_address_pool_name = "sinkPool" backend_http_settings_name = "devHttpSetting" } }
错误原因分析
- Dynamic块引用错误:外层dynamic块命名为
url_path_map,但内部错误使用outer_block.value引用属性,应改为url_path_map.value - 块名不匹配:Azure应用网关的路径规则块名是
path_rule,原代码中错误写为url_path_rule - 变量结构不匹配:main.tf传入的
path_maps未按variables.tf定义的嵌套upm列表结构传递,直接将path_rule字段放在外层对象中 - 字段类型错误:Azure应用网关的
paths要求为list(string)类型,原代码中直接传入string类型的path值
修正后代码
修正后的application_gateway.tf
dynamic "url_path_map" { for_each = var.path_maps content { name = url_path_map.value["name"] default_backend_address_pool_name = url_path_map.value["backend"] default_backend_http_settings_name = url_path_map.value["backend_set"] dynamic "path_rule" { for_each = url_path_map.value["upm"] content { name = path_rule.value["name_rule"] paths = [path_rule.value["path"]] backend_address_pool_name = path_rule.value["backend"] backend_http_settings_name = path_rule.value["backend_set"] } } } }
修正后的main.tf 模块调用
module "application_gateway" { source = "../modules/resources-hub/application_gateway" resource_group_name = module.resource_group.name resource_group_location = module.resource_group.location subnet_id = module.agw_subnet.id public_ip_address_id = module.app_gw_pip.id firewall_policy_id = module.agw_web_application_firewall.id log_analytics_workspace_id = module.log_analytics_workspace.id path_maps = [ { name = "dev_url_path_name" backend = "devBackend" backend_set = "devHttpSetting" upm = [ { name_rule = "dev_path_rule_name_app_edp" path = "/app/*" backend = "devBackend" backend_set = "devHttpSetting" }, { name_rule = "dev_path_rule_name_internal" path = "/edp/*" backend = "devBackend" backend_set = "devHttpSetting" }, { name_rule = "dev_path_rule_name_internal" path = "/internal/*" backend = "sinkPool" backend_set = "devHttpSetting" } ] } ] }
验证结果
执行terraform validate即可通过验证,生成的配置结构与预期一致。
内容的提问来源于stack exchange,提问作者Gregory
相关产品推荐
相关产品推荐

