Terraform 如何从DynamoDB复杂对象数据集中提取指定属性列表
场景说明
目前你已经跑通的配置逻辑:
- 用带
for_each的aws_dynamodb_table数据源,批量拉取多份DynamoDB表的完整元数据对象 - 基于这组对象配合
for_each生成Lambda DynamoDB流事件源映射,全流程可用 - 当前卡点:需要从这组for_each生成的对象集合里,逐表提取ARN字段组成IAM策略可直接消费的资源列表,但自己试的splat写法跑不通
为啥之前的写法失效
你写的tolist(data.aws_dynamodb_table.table.*.arn)没法正常工作,核心逻辑问题出在类型匹配上:
- 带
for_each的数据源/资源,在Terraform运行时返回的是 Map结构的对象集合:key是你传入的表名字符串,value是对应表的全部属性对象 - Terraform原生的
.*splat迭代语法,设计之初只支持穿透列表、集合类型的对象集合做批量属性提取,碰到Map结构时只会迭代Map本身的顶层属性,根本摸不到每个value内部的arn字段,自然拿不到预期结果
可直接落地的正确写法
基础版(匹配你当前的IAM配置需求)
用values()函数配合Terraform原生for表达式,是兼容所有Terraform 0.13+版本、最稳定的实现方式,对应IAM片段修改为:
statement { actions = [ "dynamodb:PutItem", "dynamodb:UpdateItem", "dynamodb:Query", "dynamodb:Scan" ] # 正确提取所有表的ARN生成资源列表 resources = [for table in values(data.aws_dynamodb_table.table) : table.arn] effect = "Allow" }
这个写法没有额外的兼容问题:
- 完全适配for_each返回的Map结构,不会出现类型不匹配报错
- 生成的结果是标准的
list(string)类型,刚好匹配IAM策略resources字段的入参要求,不需要额外做类型转换 - 不依赖for_each的key值,只聚焦你需要的表属性字段
可扩展的灵活写法
这套for表达式结构可以直接适配复杂策略需求,不需要硬编码写死每个表的ARN:
- 增加过滤逻辑:比如只给开启了数据流的表配置权限
resources = [ for table in values(data.aws_dynamodb_table.table) : table.arn if table.stream_arn != null ]
- 拼接关联资源:比如同时给表本身、表下所有二级索引配置权限
resources = flatten([ for table in values(data.aws_dynamodb_table.table) : [ table.arn, "${table.arn}/index/*" ] ])
内容的提问来源于stack exchange,提问作者tpschmidt
相关产品推荐
相关产品推荐

