I am trying to put together a really simple AWS Lambda using Serverless and DynamoDB.
My code to create an item is:
dynamoDb: DocumentClient
constructor() {
this.dynamoDb = new DynamoDB.DocumentClient({region: 'us-east-1'})
}
saveFiles(files: File[]): Promise<boolean> {
return new Promise<boolean>((resolve, reject ) => {
files.forEach(file => {
const tableName = process.env.DYNAMODB_TABLE
this.dynamoDb.put({
TableName: tableName,
Item: {
downloaded: {N : `${file.downloaded ? 1 : 0}`},
location: {S: `${file.location}`}
}
}, (error, result) => {
if (!!error) {
reject(error)
return
}
console.debug(`DB Save result: ${JSON.stringify(result)}`)
resolve(true)
})
})
})
}
The error is:
handler.ts:41
code:"ResourceNotFoundException"
message:"Requested resource not found"
name:"ResourceNotFoundException"
requestId:"2ST4DCE3NJ85UE32OAD6PUMTBJVV4KQNSO5AEMVJF66Q9ASUAAJG"
retryable:false
retryDelay:23.64284067311807
stack:"ResourceNotFoundException: Requested resource not found\n at Request.extractError (/Users/michael/Development/javascript/data-export-lambda/.webpack/service/webpack:/node_modules/aws-sdk/lib/protocol/json.js:51:1)\n at Request.callListeners (/Users/michael/Development/javascript/data-export-lambda/.webpack/service/webpack:/node_modules/aws-sdk/lib/sequential_executor.js:106:1)\n at Request.emit (/Users/michael/Development/javascript/data-export-lambda/.webpack/service/webpack:/node_modules/aws-sdk/lib/sequential_executor.js:78:1)\n at Request.emit (/Users/michael/Development/javascript/data-export-lambda/.webpack/service/webpack:/node_modules/aws-sdk/lib/request.js:683:1)\n at Request.transition (/Users/michael/Development/javascript/data-export-lambda/.webpack/service/webpack:/node_modules/aws-sdk/lib/request.js:22:1)\n at AcceptorStateMachine.runTo (/Users/michael/Development/javascript/data-export-lambda/.webpack/service/webpack:/node_modules/aws-sdk/lib/state_machine.js:14:1)\n at /Users/mi...
statusCode:400
When I query DynamoDB to list my tables I get:
aws dynamodb list-tables --endpoint-url http://localhost:8000
{
"TableNames": [
"data-export-scheduler-dev"
]
}
Table names definitely match:
My serverless.yaml is:
service:
name: data-export-scheduler
# Add the serverless-webpack plugin
plugins:
- serverless-webpack
- serverless-dynamodb-local
- serverless-offline
# serverless offline config
custom:
serverless-offline:
port: 4000
babelOptions:
presets: ["es2015"]
dynamodb:
stages:
- dev
start:
migrate: true
provider:
name: aws
region: us-east-1
runtime: nodejs8.10
environment:
DYNAMODB_TABLE: ${self:service}-${opt:stage, self:provider.stage}
iamRoleStatements:
- Effect: Allow
Action:
- dynamodb:Query
- dynamodb:Scan
- dynamodb:GetItem
- dynamodb:PutItem
- dynamodb:UpdateItem
- dynamodb:DeleteItem
Resource: "arn:aws:dynamodb:${opt:region, self:provider.region}:*:table/${self:provider.environment.DYNAMODB_TABLE}"
functions:
exportAPI:
handler: handler.exportAPI
events:
- http:
method: post
path: export
resources:
Resources:
ExportDB:
Type: 'AWS::DynamoDB::Table'
DeletionPolicy: Retain
Properties:
AttributeDefinitions:
- AttributeName: location
AttributeType: S
KeySchema:
- AttributeName: location
KeyType: HASH
ProvisionedThroughput:
ReadCapacityUnits: 1
WriteCapacityUnits: 1
TableName: ${self:provider.environment.DYNAMODB_TABLE}
Does anyone know what I could be doing wrong? The tables is there and I can query it from the DynamoDB CLI, but I keep getting the ResourceNotFoundException when trying to query it from the code.
Update 1: When I run a query from the CLI I get the same error:
aws dynamodb query --table-name data-export-scheduler-dev --key-condition-expression "downloaded = :v1" --expression-attribute-values '{":v1": { "S" : "0"}}' $LOCAL
An error occurred (ResourceNotFoundException) when calling the Query operation: Requested resource not found
I am trying to put together a really simple AWS Lambda using Serverless and DynamoDB.
My code to create an item is:
dynamoDb: DocumentClient
constructor() {
this.dynamoDb = new DynamoDB.DocumentClient({region: 'us-east-1'})
}
saveFiles(files: File[]): Promise<boolean> {
return new Promise<boolean>((resolve, reject ) => {
files.forEach(file => {
const tableName = process.env.DYNAMODB_TABLE
this.dynamoDb.put({
TableName: tableName,
Item: {
downloaded: {N : `${file.downloaded ? 1 : 0}`},
location: {S: `${file.location}`}
}
}, (error, result) => {
if (!!error) {
reject(error)
return
}
console.debug(`DB Save result: ${JSON.stringify(result)}`)
resolve(true)
})
})
})
}
The error is:
handler.ts:41
code:"ResourceNotFoundException"
message:"Requested resource not found"
name:"ResourceNotFoundException"
requestId:"2ST4DCE3NJ85UE32OAD6PUMTBJVV4KQNSO5AEMVJF66Q9ASUAAJG"
retryable:false
retryDelay:23.64284067311807
stack:"ResourceNotFoundException: Requested resource not found\n at Request.extractError (/Users/michael/Development/javascript/data-export-lambda/.webpack/service/webpack:/node_modules/aws-sdk/lib/protocol/json.js:51:1)\n at Request.callListeners (/Users/michael/Development/javascript/data-export-lambda/.webpack/service/webpack:/node_modules/aws-sdk/lib/sequential_executor.js:106:1)\n at Request.emit (/Users/michael/Development/javascript/data-export-lambda/.webpack/service/webpack:/node_modules/aws-sdk/lib/sequential_executor.js:78:1)\n at Request.emit (/Users/michael/Development/javascript/data-export-lambda/.webpack/service/webpack:/node_modules/aws-sdk/lib/request.js:683:1)\n at Request.transition (/Users/michael/Development/javascript/data-export-lambda/.webpack/service/webpack:/node_modules/aws-sdk/lib/request.js:22:1)\n at AcceptorStateMachine.runTo (/Users/michael/Development/javascript/data-export-lambda/.webpack/service/webpack:/node_modules/aws-sdk/lib/state_machine.js:14:1)\n at /Users/mi...
statusCode:400
When I query DynamoDB to list my tables I get:
aws dynamodb list-tables --endpoint-url http://localhost:8000
{
"TableNames": [
"data-export-scheduler-dev"
]
}
Table names definitely match:
My serverless.yaml is:
service:
name: data-export-scheduler
# Add the serverless-webpack plugin
plugins:
- serverless-webpack
- serverless-dynamodb-local
- serverless-offline
# serverless offline config
custom:
serverless-offline:
port: 4000
babelOptions:
presets: ["es2015"]
dynamodb:
stages:
- dev
start:
migrate: true
provider:
name: aws
region: us-east-1
runtime: nodejs8.10
environment:
DYNAMODB_TABLE: ${self:service}-${opt:stage, self:provider.stage}
iamRoleStatements:
- Effect: Allow
Action:
- dynamodb:Query
- dynamodb:Scan
- dynamodb:GetItem
- dynamodb:PutItem
- dynamodb:UpdateItem
- dynamodb:DeleteItem
Resource: "arn:aws:dynamodb:${opt:region, self:provider.region}:*:table/${self:provider.environment.DYNAMODB_TABLE}"
functions:
exportAPI:
handler: handler.exportAPI
events:
- http:
method: post
path: export
resources:
Resources:
ExportDB:
Type: 'AWS::DynamoDB::Table'
DeletionPolicy: Retain
Properties:
AttributeDefinitions:
- AttributeName: location
AttributeType: S
KeySchema:
- AttributeName: location
KeyType: HASH
ProvisionedThroughput:
ReadCapacityUnits: 1
WriteCapacityUnits: 1
TableName: ${self:provider.environment.DYNAMODB_TABLE}
Does anyone know what I could be doing wrong? The tables is there and I can query it from the DynamoDB CLI, but I keep getting the ResourceNotFoundException when trying to query it from the code.
Update 1: When I run a query from the CLI I get the same error:
aws dynamodb query --table-name data-export-scheduler-dev --key-condition-expression "downloaded = :v1" --expression-attribute-values '{":v1": { "S" : "0"}}' $LOCAL
An error occurred (ResourceNotFoundException) when calling the Query operation: Requested resource not found
Share
Improve this question
edited Jul 29, 2019 at 8:14
Michael Gaylord
asked Jul 29, 2019 at 4:58
Michael GaylordMichael Gaylord
7,3128 gold badges51 silver badges48 bronze badges
6
- have you correctly configured the AWS region according to the region your dynamodb table is in? – Thales Minussi Commented Jul 29, 2019 at 7:23
-
@ThalesMinussi yes, I have tried setting the region via the AWS global config and via the
DocumentClient
. I have updated my question to reflect it. – Michael Gaylord Commented Jul 29, 2019 at 7:36 - 1 I think I know what the problem is. DynamoDB's SDK is trying to connect to the Cloud and not to your local instance. I assume this table is not available in the Cloud. therefore you must configure the endpoint for localhost yourself – Thales Minussi Commented Jul 29, 2019 at 8:16
-
1
Something like
new AWS.DynamoDB.DocumentClient({endpoint: 'http://localhost:8000'})
– Thales Minussi Commented Jul 29, 2019 at 8:17 - 1 @ThalesMinussi Boom! That worked! D'you want add an answer so I can accept it? – Michael Gaylord Commented Jul 29, 2019 at 8:55
1 Answer
Reset to default 10By default, the AWS SDK looks up for resources in the Cloud. Therefore, when trying to connect to your DynamoDB instance, it is trying to connect to a DynamoDB table called data-export-scheduler-dev
located in us-east-1
as per your configuration.
You have to tell the SDK to look for a local DynamoDB instance, by defining the endpoint
attribute in its constructor.
Change:
constructor() {
this.dynamoDb = new DynamoDB.DocumentClient({region: 'us-east-1'})
}
to
constructor() {
this.dynamoDb = new DynamoDB.DocumentClient({region: 'us-east-1', endpoint: 'http://localhost:8000'})
}