74

I have following template that i am using in cloudformation UI to create dynamoDB table. I want to create a table with PrimaryKey as ID and sortKey as Value

{
  "AWSTemplateFormatVersion" : "2010-09-09",

  "Description" : "DB Description",

  "Resources" : {
    "TableName" : {
      "Type" : "AWS::DynamoDB::Table",
      "Properties" : {
        "AttributeDefinitions": [ { 
          "AttributeName" : "ID",
          "AttributeType" : "S"
        }, { 
          "AttributeName" : "Value",
          "AttributeType" : "S"
        } ],
        "KeySchema": [
          { 
            "AttributeName": "ID", 
            "KeyType": "HASH"
          }
        ]                
      },
      "TableName": "TableName"
    }
  }
}

On the CF UI, I click on new stack, point to the template file from my local computer, give stack a name and click next. After sometime, I get error that says Property AttributeDefinitions is inconsistent with the KeySchema of the table and the secondary indexes

Em Ae
  • 8,167
  • 27
  • 95
  • 162
  • 1
    Possible duplicate of [CloudFormation insists my DynamoDB creation JSON is invalid .. but I can't see how](http://stackoverflow.com/questions/38142870/cloudformation-insists-my-dynamodb-creation-json-is-invalid-but-i-cant-see-h) – wjordan Jan 28 '17 at 23:26
  • CloudFormation Linter rule to help catch this quicker with more information: https://github.com/aws-cloudformation/cfn-python-lint/pull/1284 – Pat Myron Jan 08 '20 at 17:53

3 Answers3

126

The issue is that the Resources.Properties.AttributeDefinitions key must only define columns used for indexes or keys. In other words, the keys in Resources.Properties.AttributeDefinitions must match the same keys defined in Resources.Properties.KeySchema.

AWS docs:

AttributeDefinitions: A list of AttributeName and AttributeType objects that describe the key schema for the table and indexes.

so the resulting template would look like this:

{
  "AWSTemplateFormatVersion" : "2010-09-09",

  "Description" : "DB Description",

  "Resources" : {
    "TableName" : {
    "Type" : "AWS::DynamoDB::Table",
    "Properties" : {
      "AttributeDefinitions": [ { 
        "AttributeName" : "ID",
        "AttributeType" : "S"
      } ],
      "ProvisionedThroughput":{
        "ReadCapacityUnits" : 1,
        "WriteCapacityUnits" : 1
      },
      "KeySchema": [
        { 
          "AttributeName": "ID", 
          "KeyType": "HASH"
        }
       ] ,               
      "TableName": "table5"
    }
   }
  }
}
rodrigo-silveira
  • 12,607
  • 11
  • 69
  • 123
jens walter
  • 13,269
  • 2
  • 56
  • 54
  • 3
    If we remove the 'value' attribute from AttributeDefinitions how can we add the 'Value' column to the table ? – Dilantha Oct 26 '17 at 16:59
  • 28
    https://stackoverflow.com/questions/25606135/how-to-add-a-column-in-dynamodb After a research, there is no need to define all your columns when you create the table, only indexes, then you can add attributes "on the go" when inserting a new row – ThomasP1988 Jan 27 '18 at 12:05
  • https://stackoverflow.com/questions/47385177/serverless-framework-dynamo-db-table-resource-definition-with-sort-key another answer which explains that – ThomasP1988 Jan 27 '18 at 12:06
  • The question stated that `Value` should be the sort key, so it should be included in the `KeySchema`, not removed from the `AttributeDefinitions`. – Jason Wadsworth Feb 12 '20 at 18:06
1

The accepted answer is correct in the cause of the error, but you said you wanted the sort key to be Value. So you should change your CloudFormation to include that:

{
  "AWSTemplateFormatVersion" : "2010-09-09",

  "Description" : "DB Description",

  "Resources" : {
    "TableName" : {
      "Type" : "AWS::DynamoDB::Table",
      "Properties" : {
        "AttributeDefinitions": [ { 
          "AttributeName" : "ID",
          "AttributeType" : "S"
        }, { 
          "AttributeName" : "Value",
          "AttributeType" : "S"
        } ],
        "KeySchema": [
          { 
            "AttributeName": "ID", 
            "KeyType": "HASH"
          },
          { 
            "AttributeName": "Value", 
            "KeyType": "RANGE"
          }
        ]                
      },
      "TableName": "TableName"
    }
  }
}
Jason Wadsworth
  • 8,059
  • 19
  • 32
0

In AttributeDefinitions you need to define just partition and range keys not other attributes.

number of attributes in AttributeDefinitions and KeySchema should match and should be exactly same.

Tanaji Sutar
  • 109
  • 1
  • 8