Terraform配置多属性DynamoDB表遇「所有属性需索引」错误求助
我来帮你理清这个问题:你遇到的报错并不是DynamoDB本身的限制,而是Terraform AWS Provider的校验逻辑搞的鬼。DynamoDB作为无模式数据库,完全支持存储未被索引的属性,也不需要提前定义所有字段。但Terraform的aws_dynamodb_table资源对attributes块有特殊要求:所有在attributes里声明的属性,必须被用作表的主键、排序键,或者某个全局/本地二级索引的键,不然就会触发这个“未使用属性”的错误。
正确的配置思路
你根本不需要在Terraform配置里把所有要存储的属性都列出来,只需要定义以下几类属性就行:
- 表的分区键(必填)
- 表的排序键(可选,按需添加)
- 所有全局二级索引(GSI)用到的分区键和排序键
- 所有本地二级索引(LSI)用到的排序键
其他属性可以直接在写入数据的时候添加,完全不需要在Terraform里提前声明。
示例配置
假设你要建一个用户表,分区键是user_id,排序键是created_at,还有一个用email做分区键的GSI,另外还要存储username、age、address这些属性,你的Terraform配置应该写成这样:
resource "aws_dynamodb_table" "user_table" { name = "UserTable" billing_mode = "PAY_PER_REQUEST" hash_key = "user_id" range_key = "created_at" attribute { name = "user_id" type = "S" } attribute { name = "created_at" type = "N" } attribute { name = "email" type = "S" } global_secondary_index { name = "EmailIndex" hash_key = "email" projection_type = "ALL" write_capacity = 5 read_capacity = 5 } # 划重点:username、age、address这些属性不需要在这里声明! }
这样配置后,terraform plan就不会再报错了,你依然可以正常写入username、age这些未在Terraform里定义的属性,DynamoDB会妥善存储它们。
为什么会有这个校验?
你找到的validateDynamoDbTableAttributes函数,是Terraform用来防止用户误操作的——attributes块的作用仅仅是声明那些会被DynamoDB的键和索引机制用到的属性,不是用来预定义表的所有字段的。如果把非键/索引属性放进attributes里,Terraform就会认为你可能搞错了,所以抛出错误提醒你。
符合DynamoDB最佳实践的小提示
虽然DynamoDB允许存大量未索引的属性,但还是给你几个建议:
- 只创建实际需要的索引,过多的索引会增加写入开销和存储成本
- 对于经常需要查询的非键属性,可以考虑把它们投影到已有的索引中,而不是新建索引
- 如果需要对多个非键属性组合查询,可以试试用全局二级索引的组合键,或者用PartiQL进行查询
内容的提问来源于stack exchange,提问作者Kateryna Khotkevych

