Iam trying to deploy my lambda function to AWS using serverless. When executing
serverless deploy --verbose
Iam getting the following error every time:
Serverless Error ---------------------------------------
An error occurred: mainTable - Invalid KeySchema: The first > KeySchemaElement is not a HASH key type (Service: AmazonDynamoDBv2;Status Code: 400; Error Code: ValidationException; Request ID: EACEH0RDMBR36TR0DDBGODTRT3VV4KQNSO5AEMVJF66Q9ASUAAJG).
My serverless.yml looks as following:
service: backend-1 # NOTE: update this with your service name
provider:
name: aws
runtime: nodejs10.x
stage: dev
region: eu-central-1
functions:
graphql:
handler: src/handler.graphql
events:
- http:
path: graphql
method: post
cors: true
plugins:
- serverless-webpack
- serverless-offline
custom:
webpack:
webpackCOnfig: 'webpack.config.js'
includeModules: true
packager: 'npm'
stage: ${opt:stage, self:provider.stage}
resources:
Resources:
mainTable:
Type: AWS::DynamoDB::Table
Properties:
TableName: main_${self:custom.stage}
AttributeDefinitions:
- AttributeName: id
AttributeType: S
- AttributeName: sort
AttributeType: S
KeySchema:
- AttributeName: id
KeyType: HASH
- AttributeName: sort
KeyType: RANGE
BillingMode: PAY_PER_REQUEST
GlobalSecondaryIndexes:
- IndexName: spinned-primary
KeySchema:
- AttributeName: id
KeyType: RANGE
- AttributeName: sort
KeyType: HASH
Projection:
ProjectionType: ALL
labelTable:
Type: AWS::DynamoDB::Table
Properties:
TableName: labels_${self:custom.stage}
AttributeDefinitions:
- AttributeName: sort
AttributeType: S
- AttributeName: label
AttributeType: S
KeySchema:
- AttributeName: sort
KeyType: HASH
- AttributeName: label
KeyType: RANGE
BillingMode: PAY_PER_REQUEST
GlobalSecondaryIndexes:
- IndexName: spinned-primary
KeySchema:
- AttributeName: sort
KeyType: RANGE
- AttributeName: label
KeyType: HASH
Projection:
ProjectionType: ALL
logTable:
Type: AWS::DynamoDB::Table
Properties:
TableName: logs_${self:custom.stage}
AttributeDefinitions:
- AttributeName: id
AttributeType: S
- AttributeName: sort
AttributeType: S
KeySchema:
- AttributeName: id
KeyType: HASH
- AttributeName: sort
KeyType: RANGE
BillingMode: PAY_PER_REQUEST
Can someone of you help?
Cheers!
When using KeySchemaElements, the HASH keytype must come before the RANGE keytype.
In your YAML, on you GSI for spinned-primary, you have to put the HASH keytype before the RANGE keytype; switch them around so that the HASH is the first keytype in that element.
Related
My apologies I'm starting with AWS and Cloudformation
I got this cloud formation template, I got Id and topic as a primary index and I would like to add a local secondary index that consists of the id and position columns to this template.
Id
topic
position
detaills
AWSTemplateFormatVersion: "2010-09-09"
Parameters:
Env:
Type: String
CommitHash:
Type: String
Resources:
RecipeRecommendationDynamoDBTable:
Type: AWS::DynamoDB::Table
Properties:
AttributeDefinitions:
- AttributeName: "id"
AttributeType: "S"
- AttributeName: "topic"
AttributeType: "S"
KeySchema:
- AttributeName: "id"
KeyType: "HASH"
- AttributeName: "topic"
KeyType: "RANGE"
TimeToLiveSpecification:
AttributeName: ttl
Enabled: true
TableName: topics_dumps
BillingMode: PAY_PER_REQUEST
Tags:
- Key: "Env"
Value: !Ref Env
You have to add LocalSecondaryIndexes:
AWSTemplateFormatVersion: "2010-09-09"
Parameters:
Env:
Type: String
CommitHash:
Type: String
Resources:
RecipeRecommendationDynamoDBTable:
Type: AWS::DynamoDB::Table
Properties:
AttributeDefinitions:
- AttributeName: "id"
AttributeType: "S"
- AttributeName: "topic"
AttributeType: "S"
- AttributeName: "position"
AttributeType: "S"
KeySchema:
- AttributeName: "id"
KeyType: "HASH"
- AttributeName: "topic"
KeyType: "RANGE"
TimeToLiveSpecification:
AttributeName: ttl
Enabled: true
LocalSecondaryIndexes:
- IndexName: position
KeySchema:
- AttributeName: "id"
KeyType: "HASH"
- AttributeName: "position"
KeyType: "RANGE"
Projection:
ProjectionType: ALL
TableName: topics_dumps
BillingMode: PAY_PER_REQUEST
Tags:
- Key: "Env"
Value: !Ref Env
I am sharing the DynamoDB cft below. I want to add a condition, so that while adding the another table the existing tables will not impact. Below template is used for creating 2 global table with name as sample1 and sample12 configuring in parameter section:
AWSTemplateFormatVersion: "2010-09-09"
Description: 'AWS CloudFormation Template for DynamoDB tables For sample Service'
Parameters:
sample1:
Type: String
Description: Select existing dynamodb table name from Parameter Store
Default: sample1
sample12:
Type: String
Description: Select existing dynamodb table name from Parameter Store
Default: sample12
Resources:
sample1:
Type: AWS::DynamoDB::GlobalTable
Properties:
BillingMode: PAY_PER_REQUEST
AttributeDefinitions:
-
AttributeName: "msgId"
AttributeType: "S"
KeySchema:
-
AttributeName: "msgId"
KeyType: "HASH"
StreamSpecification:
StreamViewType: NEW_AND_OLD_IMAGES
SSESpecification:
SSEEnabled: true
SSEType: "KMS"
Replicas:
- Region: us-east-1
TableName: !Ref sample1
sample12:
Type: AWS::DynamoDB::GlobalTable
Properties:
BillingMode: PAY_PER_REQUEST
AttributeDefinitions:
-
AttributeName: "msgId"
AttributeType: "S"
-
AttributeName: "flightNbr"
AttributeType: "S"
-
AttributeName: "recordUpdateTS"
AttributeType: "S"
-
AttributeName: "msgTypeCd"
AttributeType: "S"
-
AttributeName: "recordCreationEpochTime"
AttributeType: "S"
KeySchema:
-
AttributeName: "msgId"
KeyType: "HASH"
StreamSpecification:
StreamViewType: NEW_AND_OLD_IMAGES
SSESpecification:
SSEEnabled: true
SSEType: "KMS"
Replicas:
- Region: us-east-1
TableName: !Ref sample12
GlobalSecondaryIndexes:
-
IndexName: "FLIGHTNBR_UPDATETS_INDEX"
KeySchema:
-
AttributeName: "flightNbr"
KeyType: "HASH"
-
AttributeName: "recordUpdateTS"
KeyType: "RANGE"
Projection:
ProjectionType: "ALL"
-
IndexName: "MSGTYPE_CREATETS_INDEX"
KeySchema:
-
AttributeName: "msgTypeCd"
KeyType: "HASH"
-
AttributeName: "recordCreationEpochTime"
KeyType: "RANGE"
Projection:
ProjectionType: "ALL"
How can I add a condition or any other methods to check if table exists or not?
The only way to do this is through custom resource in the form of a lambda function. The function would use AWS SDK to perform conditional checks and create aws resources based on the outcome of these checks.
Deployment of DynamoDB stack rollbacks with error:
CREATE_FAILED Encountered unsupported property AttributeType
I tried various modifications of attributes configuration, used quotes, also checked similar question.
My template:
Resources:
checkpointsTable:
Type: AWS::DynamoDB::Table
Properties:
AttributeDefinitions:
- AttributeName: sf_instance_table_key
AttributeType: S
BillingMode: PAY_PER_REQUEST
KeySchema:
- AttributeName: sf_instance_table_key
AttributeType: HASH
TableName: !Ref tableName
Tags:
- Key: "Division"
Value: !Ref division
Not many lines here, but cannot figure it out. Thanks for help!
It should be like this:
Resources:
checkpointsTable:
Type: AWS::DynamoDB::Table
Properties:
AttributeDefinitions:
- AttributeName: sf_instance_table_key
AttributeType: S
BillingMode: PAY_PER_REQUEST
KeySchema:
- AttributeName: sf_instance_table_key
KeyType: HASH
TableName: !Ref tableName
Tags:
- Key: "Division"
Value: !Ref division
I Keep getting the following error on my serverless.yml configurations file.
"Serverless: DynamoDB - created table transactions
Validation Exception ------------------------------------
ValidationException: Provided list of item keys contains duplicates
"
What could be the problem?
Here’s the entire .yml file.
Thanks…!
service: dynamo
useDotenv: true
configValidationMode: error
frameworkVersion: ^2.52.0
provider:
name: aws
runtime: nodejs12.x
stage: dev
region: us-east-1
lambdaHashingVersion: 20201221
custom:
dynamodb:
stages:
- dev
start:
port: 8000
inMemory: true
heapInitial: 200m
heapMax: 1g
migrate: true
seed: true
convertEmptyValues: true
seed:
dev:
sources:
- table: transactions
sources: [./txs.json]
functions:
app:
handler: index.handler
events:
- http:
path: transactions
method: get
UI:
handler: index.handler
events:
- http:
path: UI
method: get
resources:
Resources:
transactionsTable:
Type: AWS::DynamoDB::Table
Properties:
TableName: transactions
AttributeDefinitions:
- AttributeName: country
AttributeType: S
- AttributeName: createdAt
AttributeType: N
KeySchema:
- AttributeName: country
KeyType: HASH
- AttributeName: createdAt
KeyType: RANGE
ProvisionedThroughput:
ReadCapacityUnits: 1
WriteCapacityUnits: 1
GlobalSecondaryIndexes:
- IndexName: country_created_at_index
KeySchema:
- AttributeName: country
KeyType: HASH
- AttributeName: createdAt
KeyType: RANGE
Projection:
ProjectionType: ALL
ProvisionedThroughput:
ReadCapacityUnits: 1
WriteCapacityUnits: 1
plugins:
- serverless-dynamodb-local
- serverless-offline
- serverless-bundle
Your GlobalSecondaryIndexes has exactly same keys are your main table. You need different key pairs. Otherwise there is no point for GlobalSecondaryIndexes.
Fixed it:
Played around with LocalSecondaryIndexes, till I did this.
service: dynamo
useDotenv: true
configValidationMode: error
frameworkVersion: ^2.52.0
provider:
name: aws
runtime: nodejs12.x
stage: dev
region: us-east-1
lambdaHashingVersion: 20201221
custom:
dynamodb:
stages:
- dev
start:
port: 8000
inMemory: true
heapInitial: 200m
heapMax: 1g
migrate: true
seed: true
convertEmptyValues: true
seed:
dev:
sources:
- table: transactions
sources: [./txs.json]
functions:
app:
handler: index.handler
events:
- http:
path: transactions/
method: get
ui:
handler: index.handler
events:
- http:
path: ui/
method: get
resources:
Resources:
transactionsTable:
Type: AWS::DynamoDB::Table
Properties:
TableName: transactions
AttributeDefinitions:
- AttributeName: id
AttributeType: S
- AttributeName: country
AttributeType: S
- AttributeName: createdAt
AttributeType: N
KeySchema:
- AttributeName: id
KeyType: HASH
- AttributeName: createdAt
KeyType: RANGE
ProvisionedThroughput:
ReadCapacityUnits: 1
WriteCapacityUnits: 1
LocalSecondaryIndexes:
- IndexName: id_index
KeySchema:
- AttributeName: id
KeyType: HASH
- AttributeName: country
KeyType: RANGE
Projection:
ProjectionType: ALL
GlobalSecondaryIndexes:
- IndexName: country_created_at_index
KeySchema:
- AttributeName: country
KeyType: HASH
- AttributeName: createdAt
KeyType: RANGE
Projection:
ProjectionType: ALL
ProvisionedThroughput:
ReadCapacityUnits: 1
WriteCapacityUnits: 1
plugins:
- serverless-dynamodb-local
- serverless-offline
- serverless-bundle
I have some code in my serverless.yml like this currently.
resources:
Resources:
uploadBucket:
Type: AWS::S3::Bucket
Properties:
BucketName: ${self:service}-${self:custom.stage}-uploads
visitsTable:
Type: AWS::DynamoDB::Table
Properties:
TableName: ${self:custom.visitsTable}
AttributeDefinitions:
- AttributeName: userId
AttributeType: S
- AttributeName: visitId
AttributeType: S
- AttributeName: comments
AttributeType: S
- AttributeName: attachments
AttributeType: S
- AttributeName: ph
AttributeType: N
- AttributeName: ch
AttributeType: N
KeySchema:
- AttributeName: userId
KeyType: HASH
- AttributeName: visitId
KeyType: HASH
ProvisionedThroughput:
ReadCapacityUnits: 5
WriteCapacityUnits: 5
My goal is to create a table with primary key userId, sort key visitId and have fields for comments, attachments, ph & ch. When I try to sls deploy I get the following error.
Serverless Error ---------------------------------------
An error occurred: visitsTable - Property AttributeDefinitions is inconsistent with the KeySchema of the table and the secondary indexes.
What am I doing wrong here?
Edit: Another attempt I tried
resources:
Resources:
uploadBucket:
Type: AWS::S3::Bucket
Properties:
BucketName: ${self:service}-${self:custom.stage}-uploads
visitsTable:
Type: AWS::DynamoDB::Table
Properties:
TableName: ${self:custom.visitsTable}
AttributeDefinitions:
- AttributeName: userId
AttributeType: S
- AttributeName: visitId
AttributeType: S
KeySchema:
- AttributeName: userId
KeyType: HASH
- AttributeName: visitId
KeyType: RANGE
ProvisionedThroughput:
ReadCapacityUnits: 5
WriteCapacityUnits: 5
AWS DynamoDb is a NO-SQL type database and no need to define all the keys during the Table creation. Also from the AWS documentation it's clear that in Attribute Definition you have to specify the Key schema and indexes.
An array of attributes that describe the key schema for the table and indexes.
Please edit your code as below
resources:
Resources:
uploadBucket:
Type: AWS::S3::Bucket
Properties:
BucketName: ${self:service}-${self:custom.stage}-uploads
visitsTable:
Type: AWS::DynamoDB::Table
Properties:
TableName: ${self:custom.visitsTable}
AttributeDefinitions:
- AttributeName: userId
AttributeType: S
- AttributeName: visitId
AttributeType: S
KeySchema:
- AttributeName: userId
KeyType: HASH
- AttributeName: visitId
KeyType: RANGE
ProvisionedThroughput:
ReadCapacityUnits: 5
WriteCapacityUnits: 5
For More CreateTable