Terraform for_each资源结合dynamic块报错问题排查
Terraform配置aws_lb_listener_rule时host_header动态块报错根源分析
问题场景
使用Terraform的aws_lb_listener_rule资源,通过for_each遍历lb_rules变量创建规则时,添加dynamic host_header块后触发错误:"Can't access attributes on a primitive-typed value (string)",移除该动态块则可正常运行。
输入变量数据
lb_rules = tolist([ { "host" = "dest-1.example.uk" "name" = "redirect-host" "path" = "/" "path_pattern" = tolist([ "", ]) "host_header" = tolist([ "origin-1.example.uk", ]) "port" = "#{port}" "priority" = 5 "protocol" = "#{protocol}" "status_code" = "HTTP_301" "type" = "dev" }, { "host" = "dest-2.example.uk" "name" = "redirect-all" "path" = "/" "path_pattern" = tolist([ "/*", ]) "host_header" = tolist([ "origin-2.example.uk", ]) "port" = "#{port}" "priority" = 100 "protocol" = "#{protocol}" "status_code" = "HTTP_301" "type" = "stage" } ])
资源配置代码
resource "aws_lb_listener_rule" "redirect" { for_each = { for r in var.lb_rules : r.name => r } listener_arn = aws_lb_listener.default.arn priority = each.value.priority action { type = "redirect" redirect { protocol = each.value.protocol host = each.value.host port = each.value.port path = each.value.path status_code = each.value.status_code } } condition { dynamic "host_header" { for_each = each.value.host_header content { values = host_header.value.*.host_header } } } tags = { Name = each.value.name } }
错误根源
问题出在dynamic host_header块的values赋值逻辑:
each.value.host_header是字符串组成的列表(比如["origin-1.example.uk"]),当dynamic循环遍历这个列表时,host_header.value对应的是单个字符串(原始primitive类型)。- 代码中
host_header.value.*.host_header试图访问该字符串的host_header属性,但字符串属于原始类型,不存在任何属性,直接触发Terraform的类型校验错误。
修正方案
aws_lb_listener_rule的condition块中,host_header的values参数需要接收字符串列表。由于循环时每个host_header.value已经是单个字符串,只需将其包装为列表即可:
condition { dynamic "host_header" { for_each = each.value.host_header content { values = [host_header.value] } } }
如果host_header列表本身就是要作为values的完整值,还可以直接简化(无需dynamic循环):
condition { host_header { values = each.value.host_header } }
内容的提问来源于stack exchange,提问作者Theo Sweeny
相关产品推荐
相关产品推荐

