Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
3
Help us understand the problem. What are the problem?
@odayushin

Serverless FrameworkでDynamoDBをローカル環境で動かす

最近、Lambdaにデプロイするコードを書いてたのですが、DynamoDBへのアクセスがあるためデプロイしないと動作確認ができず、ローカル環境でもDynamoDBを動かしたいなあと思い、調べてみました。

最初はDockerでamazon/dynamodb-localを使ってみたのですが、createTableからプログラムで書いてあげないといけないのがめんどくさくて、最終的にserverless frameworkを使う方法に落ち着きました。

必要な物

以下の4つがあれば大丈夫です。

  • Nodejs
  • npm
  • Java (ローカルDynamoDBを起動するために必要)
  • aws cli (aws configureで何かしら設定されていればOK。実際のAPIキーじゃなくても大丈夫です)

手順

プロジェクト作成

serverlessコマンドでプロジェクトを作成します。

$ npx serverless create -t aws-nodejs -p serverless-local-app

こんな感じのディレクトリ構成で作成されます

$ tree serverless-local-app

serverless-local-app
├── handler.js
└── serverless.yml

必要なプラグインをインストール

ローカルでLambdaやDynamoDBを動かすのに必要な物をインストールしていきます。

$ cd serverless-local-app
$ npm init -y
$ npm i serverless serverless-dynamodb-local aws-sdk

serverless.ymlを書き換え

serverless.ymlでDynamoDBやLambda Functionの定義をします。

serverless.yml
service: serverless-local-app
frameworkVersion: '2'
plugins:
  - serverless-dynamodb-local

provider:
  name: aws
  runtime: nodejs12.x
  stage: dev
  region: ap-northeast-1
  lambdaHashingVersion: 20201221

custom:
  dynamodb:
    stages:
      - dev
    start:
      port: 8000
      inMemory: true
      migrate: true
      seed: true
    seed:
      development:
        sources:
          - table: TableName
            sources: [./migrations/records.json]

functions:
  hello:
    handler: handler.hello

resources:
  Resources:
    TableName:
      Type: AWS::DynamoDB::Table
      Properties:
        TableName: TableName
        AttributeDefinitions:
          - AttributeName: attr1
            AttributeType: S
        KeySchema:
          - AttributeName: attr1
            KeyType: HASH
        ProvisionedThroughput:
          ReadCapacityUnits: 1
          WriteCapacityUnits: 1

テーブル初期化用のファイルを用意

migrations/records.json
[
    {
        "attr1": "value1",
        "attr2": "value2-1"
    },
    {
        "attr1": "value2",
        "attr2": "value2-2"
    },
    {
        "attr1": "value3",
        "attr2": "value2-3"
    }
]

LambdaでDynamoDBを参照するように実装

動作確認のための最低限のDynamoDBへのアクセス処理を書きます。

handler.js
"use strict";
const AWS = require("aws-sdk");
const dynamodbClient = new AWS.DynamoDB({
  endpoint: "http://localhost:8000",
});

module.exports.hello = async (event) => {
  const params = {
    TableName: "TableName",
  };
  const response = await dynamodbClient.scan(params).promise();
  console.log(JSON.stringify(response));
};

DynamoDBLocalをインストール

ローカルで動くDynamoDBをインストールします。

$ $(npm bin)/serverless dynamodb install

ローカルでDynamoDBを起動

ローカルDynamoDBを起動します。
↓のコマンドはpackage.jsonのスクリプトに書いておくと便利です。

$ $(npm bin)/serverless dynamodb start

Lambdaを実行

DynamoDBを起動した状態でLambdaをローカル実行します。helloはserverless.yml内で定義したFunction名です。

$ $(npm bin)/serverless invoke local -f hello

{"Items":[{"attr2":{"S":"value2-1"},"attr1":{"S":"value1"}},{"attr2":{"S":"value2-3"},"attr1":{"S":"value3"}},{"attr2":{"S":"value2-2"},"attr1":{"S":"value2"}}],"Count":3,"ScannedCount":3}

投入したデータを読み取って出力できていることが確認できました!

以上です。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
3
Help us understand the problem. What are the problem?