Terraform嵌套Map遍历问题:aws_autoscaling_group_tag报错解决
原代码问题
尝试通过嵌套Map遍历创建aws_autoscaling_group_tag资源时,出现类型错误:
resource "aws_autoscaling_group_tag" "test" { for_each = { host1 = { "foo1" = "bar1" "foo2" = "bar2" } host2 = { "foo1" = "bar1" "foo2" = "bar2" } } autoscaling_group_name = "doesnt-matter-getting-from-elsewhere" tag { key = each.key value = each.value propagate_at_launch = false } }
错误提示
│ Error: Incorrect attribute value type
│
│ on main.tf line 62, in resource "aws_autoscaling_group_tag" "test":
│ 62: value = each.value
│ ├────────────────
│ │ each.value is object with 2 attributes
│
│ Inappropriate value for attribute "value": string required.
╵
╷
│ Error: Incorrect attribute value type
│
│ on main.tf line 62, in resource "aws_autoscaling_group_tag" "test":
│ 62: value = each.value
│ ├────────────────
│ │ each.value is object with 2 attributes
│
│ Inappropriate value for attribute "value": string required.
问题根源:for_each遍历的是外层的host1/host2,each.value是嵌套的Map(对象类型),但tag.value要求字符串类型,导致类型不匹配。
正确实现方案
需要将嵌套的ASG-标签结构扁平化,生成每个ASG与标签的独立组合,再通过for_each遍历生成资源。
步骤1:定义扁平化的标签结构
通过locals和Terraform的flatten+嵌套for表达式,把嵌套Map转成每个元素包含ASG名称、标签键、标签值的列表:
locals { # 原始ASG-标签映射,key为ASG名称,value为该ASG的标签键值对 asg_tag_map = { "doesnt-matter-getting-from-elsewhere1" = { "foo1" = "bar1" "foo2" = "bar2" } "doesnt-matter-getting-from-elsewhere2" = { "foo1" = "bar1" "foo2" = "bar2" } } # 扁平化处理:将每个ASG的每个标签拆分为独立对象 flattened_tags = flatten([ for asg_name, tags in local.asg_tag_map : [ for tag_key, tag_value in tags : { asg_name = asg_name tag_key = tag_key tag_value = tag_value } ] ]) }
步骤2:遍历扁平化结构生成资源
将扁平化后的列表转为以ASG名称-标签键为唯一键的Map,通过for_each遍历生成对应的aws_autoscaling_group_tag资源:
resource "aws_autoscaling_group_tag" "test" { # 用"ASG名称-标签键"作为唯一标识,确保每个资源实例唯一 for_each = { for item in local.flattened_tags : "${item.asg_name}-${item.tag_key}" => item } autoscaling_group_name = each.value.asg_name tag { key = each.value.tag_key value = each.value.tag_value propagate_at_launch = false } }
效果说明
上述代码会自动生成4个独立的aws_autoscaling_group_tag资源,完全匹配需求中的手动编写结构:
- 针对
doesnt-matter-getting-from-elsewhere1生成foo1=bar1、foo2=bar2两个标签 - 针对
doesnt-matter-getting-from-elsewhere2生成foo1=bar1、foo2=bar2两个标签
内容的提问来源于stack exchange,提问作者sebastianwth

