1 year ago

#342407

test-img

sissonb

Running a Cloudformation project on localhost with DynamoDB, Lambda, and API Gateway resources using Localstack

I have a CloudFormation project with the following configs.

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
  team-up-interactions
Resources:
  handler:
    Type: AWS::Serverless::Function
    Properties:
      Description: Team Up interaction handler logic
      CodeUri: ./handler/
      Handler: handler.handler
      Runtime: nodejs14.x
      EventInvokeConfig:
        MaximumRetryAttempts: 0
      Timeout: 60
      Environment:
        Variables:
          dbStorage: !Ref dbStorage
          dbSearch: !Ref dbSearch
      Architectures:
        - x86_64
      Policies:
        - AWSLambdaBasicExecutionRole
      Events:
        HttpPost:
          Type: Api
          Properties:
            Path: '/interaction-endpoint'
            Method: post
  dbStorage:
    Type: AWS::DynamoDB::Table
    Properties:
      AttributeDefinitions:
        -
          AttributeName: "id"
          AttributeType: "S"
      KeySchema:
        -
          AttributeName: "id"
          KeyType: "HASH"
      BillingMode: "PAY_PER_REQUEST"
  dbSearch:
    Type: AWS::OpenSearchService::Domain
    Properties:
      EngineVersion: 'OpenSearch_1.1'
      ClusterConfig:
        InstanceCount: '1'
        InstanceType: 't3.small.search'
      EBSOptions:
        EBSEnabled: true
        VolumeSize: '20'
        VolumeType: 'gp2'

These configs should create a Lambda, a DynamoDB table, and an OpenSearch Domain.

I am using LocalStack's samlocal command to run the project.

samlocal local start-api --host 0.0.0.0 --warm-containers EAGER

I have the following code that attempts to connect to the DynamoDB and is failing.

    try {
        const client = new DynamoDBClient({
            endpoint: "http://localhost:4566"
        });

        await client.send(new UpdateItemCommand({
            TableName: process.env.dbStorage,
            Key: marshall({id: "test"}),
            ExpressionAttributeValues: marshall({":test": "hello world"}),
            UpdateExpression: "SET test = :test",
        }));
        //
        const x = await client.send(new GetItemCommand({
            TableName: process.env.dbStorage,
            Key: marshall({id: "test"}),
        }))

        console.log("JSON.stringify(x)");
        console.log(JSON.stringify(x));
    } catch (ex) {
        console.log("JSON.stringify(ex)")
        console.log(JSON.stringify(ex))
    }

This is the error.

{
  "errno": -111,
  "code": "ECONNREFUSED",
  "syscall": "connect",
  "address": "127.0.0.1",
  "port": 4566,
  "$metadata": {
    "attempts": 1,
    "totalRetryDelay": 0
  }
}

I also tried creating the client without any parameter and that failed too.

const client = new DynamoDBClient();

This is the error.

{
  "name": "UnrecognizedClientException",
  "$fault": "client",
  "$metadata": {
    "httpStatusCode": 400,
    "requestId": "VAHE0KG1D1UTE9AQNAREF9RJHFVV4KQNSO5AEMVJF66Q9ASUAAJG",
    "attempts": 1,
    "totalRetryDelay": 0
  },
  "__type": "com.amazon.coral.service#UnrecognizedClientException",
  "message": "The security token included in the request is invalid."
}

How can I get LocalStack to create the DynamoDB resource from the configurations and/or how do I access those resources?

Update

I am using this endpoint and it seems to be able to connect the client to localstack.

        const client = new DynamoDBClient({
            endpoint: "http://host.docker.internal:4566",
        });

I get the following error when doing a GetItemCommand

ResourceNotFoundException: Cannot do operations on a non-existent table                                                                                   
    at deserializeAws_json1_0ResourceNotFoundExceptionResponse (/var/task/node_modules/@aws-sdk/client-dynamodb/dist-cjs/protocols/Aws_json1_0.js:3036:23)
    at deserializeAws_json1_0GetItemCommandError (/var/task/node_modules/@aws-sdk/client-dynamodb/dist-cjs/protocols/Aws_json1_0.js:1729:25)
    at processTicksAndRejections (internal/process/task_queues.js:95:5)
    at async /var/task/node_modules/@aws-sdk/client-dynamodb/node_modules/@aws-sdk/middleware-serde/dist-cjs/deserializerMiddleware.js:7:24
    at async /var/task/node_modules/@aws-sdk/client-dynamodb/node_modules/@aws-sdk/middleware-signing/dist-cjs/middleware.js:11:20
    at async StandardRetryStrategy.retry (/var/task/node_modules/@aws-sdk/client-dynamodb/node_modules/@aws-sdk/middleware-retry/dist-cjs/StandardRetryStrategy.js:51:46)
    at async /var/task/node_modules/@aws-sdk/client-dynamodb/node_modules/@aws-sdk/middleware-logger/dist-cjs/loggerMiddleware.js:6:22
    at async module.exports (/var/task/interaction/instant/help/help.js:31:19)
    at async Runtime.exports.handler (/var/task/handler.js:94:16) {
  '$fault': 'client',
  '$metadata': {
    httpStatusCode: 400,
    requestId: '3ad8e2c9-be76-449d-bc86-4b529f3ca45b',
    extendedRequestId: undefined,
    cfId: undefined,
    attempts: 1,
    totalRetryDelay: 0
  },
  __type: 'com.amazonaws.dynamodb.v20120810#ResourceNotFoundException'
}

aws-lambda

amazon-dynamodb

aws-cloudformation

localstack

0 Answers

Your Answer

Accepted video resources