Terraform动态创建多DynamoDB表遇属性类型不匹配错误求助
解决Terraform批量创建多属性DynamoDB表的错误
错误原因分析
- 变量
dynamodb_table中attribute字段定义为单个object,但terraform.tfvars中传入的是列表对象,类型不匹配导致报错。 main.tf中动态属性循环错误引用了不存在的var.attributes,应指向当前表的属性列表。- 全局GSI变量独立于表配置,无法实现每个表的个性化GSI需求。
ttl_enabled定义为string类型,不符合Terraform对该参数的bool类型要求;write_capacity定义为string,应为number类型。
修正后的代码实现
1. 修正变量声明(variable.tf)
调整attribute为列表类型,修正字段类型,将GSI嵌入表对象作为可选配置:
variable "dynamodb_table" { type = list(object({ table_name = string billing_mode = string read_capacity = optional(number) write_capacity = optional(number) # 修正为number类型 hash_key = string ttl_attribute_name = string ttl_enabled = bool # 修正为bool类型 range_key = optional(string) attributes = optional(list(object({ # 改为列表类型,命名更规范 name = string type = string }))) global_secondary_indexes = optional(list(object({ # GSI嵌入表配置,支持独立定义 index_name = string index_projection_type = string index_range_key = optional(string) index_hash_key = string index_write_capacity = optional(number) index_read_capacity = optional(number) index_non_key_attributes = optional(list(string)) }))) })) } variable "default_tags" { type = map(string) default = {} }
2. 修正配置文件(terraform.tfvars)
对应变量调整,修正字段名称和类型,为每个表配置独立属性和GSI:
dynamodb_table = [ { table_name = "devops-test-01", billing_mode = "PAY_PER_REQUEST", hash_key = "UserId", range_key = "GameTitle", ttl_attribute_name = "ttl_attribute_name", ttl_enabled = false # 改为布尔值,无需引号 attributes = [ { name = "UserId" type = "S" }, { name = "GameTitle" type = "S" }, { name = "Id" type = "S" } ], global_secondary_indexes = [ { index_name = "TitleIndex" index_hash_key = "UserId" index_range_key = "GameTitle" index_projection_type = "INCLUDE" index_non_key_attributes = ["Id"] } ] }, { table_name = "devops-test-02", billing_mode = "PAY_PER_REQUEST", hash_key = "GameTitle", ttl_attribute_name = "ttl_attribute_name", ttl_enabled = false, attributes = [ { name = "GameTitle" type = "S" } ] # 该表无需GSI,可省略配置 } ] default_tags = { "Environment" = "Dev", "Owner" = "xxx" }
3. 修正资源配置(main.tf)
修复动态块循环引用,支持每个表的独立属性和GSI:
resource "aws_dynamodb_table" "basic-dynamodb-table" { for_each = { for idx, table in var.dynamodb_table : table.table_name => table } # 用表名作为键,更直观 name = each.value.table_name billing_mode = each.value.billing_mode read_capacity = each.value.read_capacity write_capacity = each.value.write_capacity hash_key = each.value.hash_key range_key = each.value.range_key # TTL配置 ttl { attribute_name = each.value.ttl_attribute_name enabled = each.value.ttl_enabled } # 动态生成表属性 dynamic "attribute" { for_each = each.value.attributes != null ? each.value.attributes : [] # 处理可选属性列表 content { name = attribute.value.name type = attribute.value.type } } # 动态生成全局二级索引 dynamic "global_secondary_index" { for_each = each.value.global_secondary_indexes != null ? each.value.global_secondary_indexes : [] content { name = global_secondary_index.value.index_name hash_key = global_secondary_index.value.index_hash_key projection_type = global_secondary_index.value.index_projection_type range_key = global_secondary_index.value.index_range_key read_capacity = global_secondary_index.value.index_read_capacity write_capacity = global_secondary_index.value.index_write_capacity non_key_attributes = global_secondary_index.value.index_non_key_attributes } } tags = merge( var.default_tags, { Name = each.value.table_name } ) }
验证方法
- 执行
terraform init初始化环境。 - 执行
terraform plan查看执行计划,确认会创建两个符合预期的DynamoDB表,每个表的属性和GSI独立。 - 执行
terraform apply完成创建。
内容的提问来源于stack exchange,提问作者beginnertopython
相关产品推荐
相关产品推荐

