skip to Main Content

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


  1. 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.

    Login or Signup to reply.
  2. 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).

    Use the AWS Serverless Application Model Command Line Interface (AWS SAM CLI) sam local start-lambda subcommand to invoke your AWS Lambda function through the AWS Command Line Interface (AWS CLI) or SDKs. This command starts a local endpoint that emulates AWS Lambda.

    https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/using-sam-cli-local.html

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search