LoginSignup
3
1

More than 1 year has passed since last update.

【Serverless Framework】S3イベントでLambda起動をローカルで実行したい

Last updated at Posted at 2021-07-20

前記事でserverless frameworkでのローカル環境構築方法を勉強してみたのですが、その続きみたいな記事になります。
今回はS3イベントをトリガーにしてLambdaを起動し、LambdaがS3やDynamoDBにアクセスするような構成を想定してローカルに動作確認用の環境を構築していきます。

ローカルに構築するインフラ構成

image.png

必要な物

  • Nodejs
  • npm
  • Java
  • awscli

手順

やっていきます。

プロジェクト作成

$ npx serverless create -t aws-nodejs -p local-s3-lambda-app
$ cd local-s3-lambda-app
$ npm init -y

必要なモジュール類をインストール

$ npm i serverless serverless-dynamodb-local serverless-s3-local aws-sdk

Lambdaとして動かす関数を用意

2つLambdaを作成します。

  1. S3にオブジェクトをPutするLambda(trigger)
  2. S3イベントでトリガーされるLambda(handler)
s3_trigger.js
"use strict";
const AWS = require("aws-sdk");
const fs = require("fs");
const s3Client = new AWS.S3({
  s3ForcePathStyle: true,
  accessKeyId: "S3RVER",
  secretAccessKey: "S3RVER",
  endpoint: new AWS.Endpoint("http://localhost:4569"),
});

module.exports.trigger = async (event, context, callback) => {
  const uploadFile = fs.readFileSync("./upload_data/upload_data.json");
  const params = {
    Bucket: "local-bucket",
    Key: "upload_data.json",
    Body: uploadFile,
  };
  const response = await s3Client
    .putObject(params)
    .promise()
    .catch((err) => {
      console.log(err, err.stack);
    });
  console.log("OK");
  callback();
};

handler.js

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

module.exports.handler = async (event) => {
  const params = {
    TableName: "SomeTable",
  };
  const response = await dynamodbClient
    .scan(params)
    .promise()
    .catch((err) => console.log(err));
  console.log(JSON.stringify(response, null, 1));
};

serverless.ymlを修正

serverless.ymlにローカルで動かすS3とDynamoDBとLambdaを記述します。

serverless.yml
service: local-s3-lambda-app
configValidationMode: error
frameworkVersion: "2"

plugins:
  - serverless-s3-local
  - serverless-dynamodb-local

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

custom:
  s3:
    host: localhost
    directory: ./local_s3
  dynamodb:
    stages:
      - dev
    start:
      port: 8000
      inMemory: true
      migrate: true
      seed: true
    seed:
      development:
        sources:
          - table: SomeTable
            sources: [./seed/records.json]

resources:
  Resources:
    NewResource:
      Type: AWS::S3::Bucket
      Properties:
        BucketName: local-bucket
      Resources:
    SomeTable:
      Type: AWS::DynamoDB::Table
      Properties:
        TableName: SomeTable
        AttributeDefinitions:
          - AttributeName: attr1
            AttributeType: S
        KeySchema:
          - AttributeName: attr1
            KeyType: HASH
        ProvisionedThroughput:
          ReadCapacityUnits: 1
          WriteCapacityUnits: 1

functions:
  trigger:
    handler: s3_trigger.trigger
  handler:
    handler: handler.handler
    events:
      - s3:
          bucket: local-bucket
          event: s3:Put

必要なファイルを追加

S3にPutするファイルとDynamoDBに初期投入するデータを用意します。

S3用

$ mkdir upload_data
$ touch upload_data/upload_data.json
$ echo '{}' > upload_data/upload_data.json

DynamoDB用

$ mkdir seed
$ touch seed/records.json
records.json
[
  {
    "attr1": "value1-1",
    "attr2": "value2-1",
    "attr3": "value3-1"
  },
  {
    "attr1": "value1-2",
    "attr2": "value2-2",
    "attr3": "value3-2"
  }
]

localDynamoDBをインストール

$ $(npm bin)/sls dynamodb install

ローカルで起動してみる

順番はこんな感じです

  1. S3を起動する
  2. DynamoDBを起動する
  3. Lambda(s3_trigger)をinvoke localする

S3イベントがhandlerをinvokeしてDynamoDBのレコードがコンソールに出力されていればOKです。

$ $(npm bin)/sls s3 start
$ $(npm bin)/sls dynamodb start
$ $(npm bin)/sls invoke local -f trigger

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

無事出力されました!

終わりに

ローカルでS3イベントからLambda起動してDynamoDBの読み取りまでできちゃうのはすごいですね。
他にもapi-gatewayも動かせたりするので、まだまだローカルでの実行環境構築はいろんなことができそうです。
以上です。

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1