To test locally, I am using SAM for my lambda function. And using DynamoDB local. It seems my lambda cannot connect to DynamoDB local
When I run java -Djava.library.path=./DynamoDBLocal_lib -jar DynamoDBLocal.jar -sharedDb
command, I get output
Initializing DynamoDB Local with the following configuration:
Port: 8000
InMemory: false
DbPath: null
SharedDb: true
shouldDelayTransientStatuses: false
CorsParams: null
When I run aws dynamodb list-tables --endpoint-url http://localhost:8000
command, I get output
{
"TableNames": [
"User"
]
}
Which based on my knowledge, indicates that DynamoDB local is running in http://localhost:8000 and can be accessed through aws-cli
Here’s my template file
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
login
Sample SAM Template for login
# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
Function:
Timeout: 300
Tracing: Active
Api:
TracingEnabled: true
Resources:
MyLambdaRole:
Type: AWS::IAM::Role
Properties:
RoleName: MyLambdaRole
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: lambda.amazonaws.com
Action: sts:AssumeRole
Policies:
- PolicyName: DynamoDBPolicy
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- dynamodb:Query
- dynamodb:Scan
- dynamodb:GetItem
- dynamodb:PutItem
- dynamodb:UpdateItem
- dynamodb:DeleteItem
Resource: "arn:aws:dynamodb:localhost:localhost:table/User"
HelloWorldFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: hello-world/
Handler: app.lambdaHandler
Runtime: nodejs18.x
Architectures:
- x86_64
Events:
HelloWorld:
Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
Path: /hello
Method: post
Environment:
Variables:
TABLE_NAME: "User"
DYNAMODB_LOCAL_ENDPOINT: http://localhost:8000
Role: !GetAtt MyLambdaRole.Arn
Outputs:
# ServerlessRestApi is an implicit API created out of Events key under Serverless::Function
# Find out more about other implicit resources you can reference within SAM
# https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api
HelloWorldApi:
Description: API Gateway endpoint URL for Prod stage for Hello World function
Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello/"
HelloWorldFunction:
Description: Hello World Lambda Function ARN
Value: !GetAtt HelloWorldFunction.Arn
HelloWorldFunctionIamRole:
Description: Implicit IAM Role created for Hello World function
Value: !GetAtt MyLambdaRole.Arn
And here is my lambda function
import AWS from 'aws-sdk';
import bcrypt from 'bcrypt';
export const lambdaHandler = async (event, context) => {
const dynamoDB = new AWS.DynamoDB.DocumentClient({
region: 'localhost',
endpoint: 'http://localhost:8000'
});
const params = {
TableName: process.env.TABLE_NAME,
Select: 'COUNT',
};
const result = await dynamoDB.scan(params).promise();
return result
}
I get the error:
{"errorType": "UnknownEndpoint", "errorMessage": "Inaccessible host: `localhost' at port `8000'. This service may not be available in the `localhost' region.", "trace": ["UnknownEndpoint: Inaccessible host: `localhost' at port `8000'. This service may not be available in the `localhost' region.", " at Request.ENOTFOUND_ERROR (/var/task/node_modules/aws-sdk/lib/event_listeners.js:611:46)", " at Request.callListeners (/var/task/node_modules/aws-sdk/lib/sequential_executor.js:106:20)", " at Request.emit (/var/task/node_modules/aws-sdk/lib/sequential_executor.js:78:10)", " at Request.emit (/var/task/node_modules/aws-sdk/lib/request.js:686:14)", " at error (/var/task/node_modules/aws-sdk/lib/event_listeners.js:443:22)", " at ClientRequest.<anonymous> (/var/task/node_modules/aws-sdk/lib/http/node.js:100:9)", " at ClientRequest.emit (node:events:517:28)", " at ClientRequest.emit (node:domain:489:12)", " at Socket.socketErrorListener (node:_http_client:501:9)", " at Socket.emit (node:events:517:28)"]}
I am quite stuck here. Not sure what course of action to take from here. Any help would be appreciated
2
Answers
My guess is you don’t know what localhost means. It means "the host I’m on right now". Thus it works as a host address when you’re on the same machine as you’ve setup DynamoDB Local. But then when your Lambda (which is running in an AWS context on some AWS-maintained box) is told to connect to "localhost" it’s looking at itself which isn’t getting you very far.
If you’re using Lambda, use the real DynamoDB.
You don’t make it clear if you’re using Lambda local with SAM or not. If you need to use DynamoDB Local with Lambda, then your Lambda function must also be running on local (on the same host).
https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/using-sam-cli-local.html