简体   繁体   English

Terraform + DynamoDB:必须为所有属性编制索引

[英]Terraform + DynamoDB: All attributes must be indexed

I want to create a Terraform configuration for DynamoDB table with multiple (> 10) attributes.我想为具有多个(> 10 个)属性的 DynamoDB 表创建一个 Terraform 配置。 And I have no need to add all attributes as an index to global_secondary_index or local_secondary_index .而且我不需要将所有属性作为索引添加到global_secondary_indexlocal_secondary_index But when I run terraform plan command I have next error:但是当我运行terraform plan命令时,出现下一个错误:

All attributes must be indexed. Unused attributes: ...

I found the validation check in the Terraform repository in validateDynamoDbTableAttributes function.我在 Terraform 存储库的validateDynamoDbTableAttributes function 中找到了验证检查。

But also as I know the best practice is that each table in DynamoDB is limited to a maximum of five global secondary indexes and five local secondary indexes from General Guidelines for Secondary Indexes in DynamoDB .但据我所知,最佳实践是each table in DynamoDB is limited to a maximum of five global secondary indexes and five local secondary indexes ,来自DynamoDB 中二级索引的一般指南

And since I have more than 10 attributes it looks like a problem to me.因为我有超过 10 个属性,所以这对我来说是个问题。

What I would like to understand why all attributes must be indexed and what to do in case if you have a big number of attributes.我想了解为什么必须对所有属性进行索引以及如果您有大量属性该怎么办。

Thanks!谢谢!

You do not have to define every attribute you want to use up front when creating your table.不必定义要创建表时使用了前面所有的属性。

attribute blocks inside aws_dynamodb_table resources are not defining which attributes you can use in your application. aws_dynamodb_table资源中的attribute没有定义您可以在应用程序中使用哪些属性。 They are defining the key schema for the table and indexes .他们正在定义表和索引的关键模式

For example, the following Terraform defines a table with only a hash key:例如,以下 Terraform 定义了一个只有一个哈希键的表:

resource "aws_dynamodb_table" "test" {
  name           = "test-table-name"
  read_capacity  = 10
  write_capacity = 10
  hash_key       = "Attribute1"

  attribute {
    name = "Attribute1"
    type = "S"
  }
}

Every item in this table has Attribute1 , but you can create additional attributes with your application此表中的每个项目都有Attribute1 ,但您可以使用您的应用程序创建其他属性两个项目,都具有 Attribute1,但自定义属性不同

This means that you can have your 10+ attributes as long as you don't need to define them in an AttributeDefinition , and since you say you don't need them to be indexed, you'll be fine.这意味着您可以拥有 10 多个属性,只要您不需要在AttributeDefinition定义它们,并且既然您说不需要将它们编入索引,那么您就可以了。

For some discussion of the confusion ( attribute is confusing and doesn't match the DynamoDB API), see this pull request .有关混淆的一些讨论( attribute令人困惑并且与 DynamoDB API 不匹配),请参阅此拉取请求

I was adding a projected field to an LSI and put an attribute entry in for the projected field.我正在向 LSI 添加一个投影字段,并为投影字段添加一个属性条目。 This was causing the error.这导致了错误。 You can just list the projected field in the non_key_attributes as shown below, it doesn't have to be defined as an attribute since it's not a key:您可以只在 non_key_attributes 中列出投影字段,如下所示,它不必定义为属性,因为它不是键:

local_secondary_index {
  name = "allocated_plus_created-lsi"
  range_key = "allocated_plus_created"
  projection_type = "INCLUDE"
  non_key_attributes = ["allocated"]
}

Allocated shouldn't be defined as an attribute for TF.分配不应定义为 TF 的属性。

DynamoDB is a schema-less database, meaning you do not need to define all the attributes on creation, but you do need to be very explicit about the primary attributes and indexes at the beginning. DynamoDB 是无模式数据库,这意味着您无需在创建时定义所有属性,但您确实需要在开始时非常明确地说明主要属性和索引。 Each declared attribute need an explicit index hence the error All attributes must be indexed .每个声明的属性都需要一个显式索引,因此会出现错误All attributes must be indexed

For example, the below code will require Email and Timestamp on any new entries:例如,以下代码将需要Email和任何新条目的Timestamp

provider "aws" {
  region = var.region
}

module "dynamodb_table_1" {
  source              = "../../"
  name                = "Subscribed_Users"
  hash_key            = "Email"
  range_key           = "Timestamp"
  enable_autoscaler   = false
  dynamodb_attributes = [
    {
      name = "Email"
      type = "S"
    }
  ]

  local_secondary_index_map = [
    {
      name               = "EmailAndTimestampSortIndex"
      hash_key           = "Email"
      range_key          = "Timestamp"
      projection_type    = "INCLUDE"
      non_key_attributes = ["Email", "Timestamp"]
    },
  ]

  context = module.this.context
}

Below are both valid inserts (as it contains both email and timestamp):以下是两个有效的插入(因为它同时包含 email 和时间戳):

First Entry第一次入境

{
  "Email": {
    "S": "foo@foo.com"
  },
  "Timestamp": {
    "S": "Wed, 18 Jan 2023 01:45:40 GMT"
  },
  "Address": {
    "M": {
      "Country": {
        "S": "Australia"
      }
    }
  },
  "Name": {
    "S": "Melchor"
  }
}

Second Entry二次入场

{
      "Email": {
        "S": "foo2@foo.com"
      },
      "Timestamp": {
        "S": "Wed, 18 Jan 2023 01:45:40 GMT"
      },
      "Name": {
        "S": "Bob"
      }
}

Inserted Values:插入值: 在此处输入图像描述

For an extensive explanation on what hash and range keys are see: https://stackoverflow.com/a/27348364/2023728有关 hash 和范围键的详细说明,请参阅: https://stackoverflow.com/a/27348364/2023728

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM