LocalStack上にServerlessでAPI Gateway、Lambda、DynamoDBを構築してみる
はじめに
LocalStack上にServerless Frameworkを使用して「LocalStack上にAPI Gateway、Lambda、DynamoDB環境を構築してみる」と同じ環境を構築する。
CurlでApiを叩き。LambdaでDynamoDBからデータを取得しレスポンスを返す処理を実装する。
動作確認環境
「WSL2上のUbuntu 20.04でLocalStackを使ってみる」で構築した環境を使い作成する。
Guest OS (WSL2)
追加アイテムだけ記載する。
- Ubuntu 20.04
- node: 16.13.1
- npm: 8.1.2
- serverless: 2.69.1
- serverless-localstack: 0.4.35
準備
作業フォルダー作成
hoge@AA:~$ mkdir aws-serverless
hoge@AA:~$ cd aws-serverless
node.jsを準備する
nvmインストールする
必要に応じて、nvmのインストール手順を確認して指定を変更する。
hoge@AA:~/aws-serverless$ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
hoge@AA:~/aws-serverless$ source ~/.bashrc
hoge@AA:~/aws-serverless$ command -v nvm
nvm
node.jsのLTS版をインストールする。[1]
hoge@AA:~/aws-serverless$ nvm install --lts
Installing latest LTS version.
Downloading and installing node v16.13.1...
Downloading https://nodejs.org/dist/v16.13.1/node-v16.13.1-linux-x64.tar.xz...
##################################################################################################### 100.0%
Computing checksum with sha256sum
Checksums matched!
Now using node v16.13.1 (npm v8.1.2)
Creating default alias: default -> lts/* (-> v16.13.1)
hoge@AA:~/aws-serverless$ node --version
v16.13.1
hoge@AA:~/aws-serverless$ npm --version
8.1.2
npmをバージョンアップする。[2]
hoge@AA:~/aws-serverless$ npm install -g npm@8.3.0
Serverless Frameworkを準備する
Serverless Frameworkをインストールする。
hoge@AA:~/aws-serverless$ npm i -g serverless
hoge@AA:~/aws-serverless$ serverless --version
Framework Core: 2.69.1
Plugin: 5.5.1
SDK: 4.3.0
Components: 3.18.1
Serverless Framework向けのLocalStackプラグインをインストールする。
hoge@AA:~/aws-serverless$ npm i -D serverless-localstack
hoge@AA:~/aws-serverless$ cat node_modules/serverless-localstack/package.json | jq .version
"0.4.35"
docker-composeを準備する
docker-compose.ymlファイルを作成する。
必要なSERVICESを指定する。
serverlessが使用する、s3,iam,sts,cloudformationをSERVICESに追加している。[3]
serverless.ymlを編集する。
hoge@AA:~/aws-serverless$ vi docker-compose.yml
version: "3.8"
services:
localstack:
container_name: "${LOCALSTACK_DOCKER_NAME-localstack_main}"
image: localstack/localstack:0.13.1
network_mode: bridge
ports:
- "4566:4566"
- "4571:4571"
environment:
- SERVICES=apigateway,lambda,dynamodb,s3,iam,sts,cloudformation
- DEBUG=${DEBUG- }
- DATA_DIR=${DATA_DIR- }
- LAMBDA_EXECUTOR=${LAMBDA_EXECUTOR- }
- LOCALSTACK_API_KEY=${LOCALSTACK_API_KEY- } # only required for Pro
- HOST_TMP_FOLDER=${TMPDIR:-/tmp/}localstack
- DOCKER_HOST=unix:///var/run/docker.sock
- LAMBDA_EXECUTOR=docker-reuse
volumes:
- "${TMPDIR:-/tmp}/localstack:/tmp/localstack"
- "/var/run/docker.sock:/var/run/docker.sock"
docker-compose.ymlの編集を保存して終了する。(escキーを押す。「:wq」を入力してエンターキーを押す。)
LocalStackを立ち上げる。[4]
hoge@AA:~/aws-serverless$ docker-compose up -d
Serverless Frameworkの設定
プロジェクト作成
serverlessコマンドでPython3用のプロジェクトを作成する。
hoge@AA:~/aws-serverless$ serverless create --template aws-python3 --path python3-localstack
Serverless: Generating boilerplate...
Serverless: Generating boilerplate in "/home/hoge/aws-serverless/python3-localstack"
Serverless: Successfully generated boilerplate for template: "aws-python3"
hoge@AA:~/aws-serverless$ cd python3-localstack
hoge@AA:~/aws-serverless/python3-localstack$
serverless.yml
serverless.ymlを編集する。
hoge@AA:~/aws-serverless/python3-localstack$ vi serverless.yml
API Gatewayにするため、「functions→users→events→http」にする必要がある。
httpApiはAPI Gateway V2になるためProが必要。
service: python3-localstack
frameworkVersion: '2'
provider:
name: aws
runtime: python3.8
lambdaHashingVersion: 20201221
region: us-east-1
profile: localstack
environment:
DYNAMODB_TABLE: myUserTable
iamRoleStatements:
- Effect: Allow
Action:
- dynamodb:Query
- dynamodb:Scan
- dynamodb:GetItem
- dynamodb:PutItem
- dynamodb:UpdateItem
- dynamodb:DeleteItem
Resource: "arn:aws:dynamodb:${opt:region, self:provider.region}:*:table/${self:provider.environment.DYNAMODB_TABLE}"
functions:
users:
handler: handler.getUsers
events:
- http:
path: users
method: get
cors: true
resources:
Resources:
usersTable:
Type: AWS::DynamoDB::Table
Properties:
TableName: ${self:provider.environment.DYNAMODB_TABLE}
AttributeDefinitions:
- AttributeName: Name
AttributeType: S
- AttributeName: Index
AttributeType: N
KeySchema:
- AttributeName: Name
KeyType: HASH
- AttributeName: Index
KeyType: RANGE
ProvisionedThroughput:
ReadCapacityUnits: 10
WriteCapacityUnits: 5
plugins:
- serverless-localstack
custom:
localstack:
stages:
- local
serverless.ymlの編集を保存して終了する。(escキーを押す。「:wq」を入力してエンターキーを押す。)
handler.py
handler.pyを編集する。
hoge@AA:~/aws-serverless/python3-localstack$ vi handler.py
import os
import boto3
from boto3.session import Session
from datetime import datetime
session = Session(
aws_access_key_id='dummy',
aws_secret_access_key='dummy',
region_name='us-east-1'
)
if os.getenv('LOCALSTACK_HOSTNAME') is None:
endpoint = 'http://localhost:4566'
else:
endpoint=f"http://{os.environ['LOCALSTACK_HOSTNAME']}:4566"
dynamodb = session.resource(
service_name='dynamodb',
endpoint_url=endpoint
)
def getUsers(event, context):
table = dynamodb.Table('myUserTable')
data = []
response = table.scan()
while True:
data.extend(response["Items"])
if "LastEvaluatedKey" not in response:
break
response = table.scan(ExclusiveStartKey=response["LastEvaluatedKey"])
return {
'statusCode': 200,
'body':{
'users':data
}
}
handler.pyの編集を保存して終了する。(escキーを押す。「:wq」を入力してエンターキーを押す。)
動作確認
デプロイ
serverlessコマンドでLocalStackへデプロイする。
hoge@AA:~/aws-serverless/python3-localstack$ serverless deploy -s local
Serverless: Using serverless-localstack
Serverless: Packaging service...
〜中略〜
Serverless: Checking Stack update progress...
...............
Serverless: Stack update finished...
Service Information
service: python3-localstack
stage: local
region: us-east-1
stack: python3-localstack-local
resources: 13
api keys:
None
endpoints:
http://localhost:4566/restapis/XXXXXXXX/local/_user_request_
functions:
users: python3-localstack-local-users
layers:
None
アイテムの追加
DynamoDBアイテム追加する。
hoge@AA:~/aws-serverless/python3-localstack$ awslocal dynamodb put-item --table-name myUserTable \
--item '{"Name":{"S": "Ishida Mio"}, "Index":{"N": "1000"}, "Gender":{"S": "Female"}, "Tel":{"S": "0769625106"}, "Mail":{"S": "mio1094@ccfrevk.ll"}, "Birthday":{"S": "1982/02/26"}}' \
--profile=localstack
hoge@AA:~/aws-serverless/python3-localstack$ awslocal dynamodb put-item --table-name myUserTable \
--item '{"Name":{"S": "Shimura Kokoro"}, "Index":{"N": "1001"}, "Gender":{"S": "Female"}, "Tel":{"S": "0829490871"}, "Mail":{"S": "kokoro414@bevhlk.xju"}, "Birthday":{"S": "1990/02/17"}}' \
--profile=localstack
hoge@AA:~/aws-serverless/python3-localstack$ awslocal dynamodb put-item --table-name myUserTable \
--item '{"Name":{"S": "Ishimura Masaki"}, "Index":{"N": "1002"}, "Gender":{"S": "Male"}, "Tel":{"S": "0848254480"}, "Mail":{"S": "masaki_ishimura@kokn.qgj"}, "Birthday":{"S": "1992/06/20"}}' \
--profile=localstack
hoge@AA:~/aws-serverless/python3-localstack$ awslocal dynamodb put-item --table-name myUserTable \
--item '{"Name":{"S": "Shirai Tomoko"}, "Index":{"N": "1003"}, "Gender":{"S": "Female"}, "Tel":{"S": "0742216492"}, "Mail":{"S": "tomoko225@vlyqs.pxt"}, "Birthday":{"S": "1982/09/29"}}' \
--profile=localstack
hoge@AA:~/aws-serverless/python3-localstack$ awslocal dynamodb put-item --table-name myUserTable \
--item '{"Name":{"S": "Yasui Tomoyuki"}, "Index":{"N": "1004"}, "Gender":{"S": "Male"}, "Tel":{"S": "095953680"}, "Mail":{"S": "tomoyuki772@jheauwpl.lyo"}, "Birthday":{"S": "1996/04/23"}}' \
--profile=localstack
API呼び出し
APIを呼び出してレスポンスを確認する。
APIはデプロイのendpointsとfunctionsを組み合わせたものになります。
curl -X GET -s http://localhost:4566/restapis/XXXXXXXX/local/_user_request_/users | jq
{
"users": [
{
"Index": 1000,
"Tel": "0769625106",
"Birthday": "1982/02/26",
"Gender": "Female",
"Mail": "mio1094@ccfrevk.ll",
"Name": "Ishida Mio"
},
{
"Index": 1002,
"Tel": "0848254480",
"Birthday": "1992/06/20",
"Gender": "Male",
"Mail": "masaki_ishimura@kokn.qgj",
"Name": "Ishimura Masaki"
},
{
"Index": 1001,
"Tel": "0829490871",
"Birthday": "1990/02/17",
"Gender": "Female",
"Mail": "kokoro414@bevhlk.xju",
"Name": "Shimura Kokoro"
},
削除
serverless.yml設定の問題かECRのエラーが出て使えない。[5]
hoge@AA:~/aws-serverless/python3-localstack$ serverless remove -s local
参考にしたサイト
- Serverless FrameworkをLocalStackで使ってみる(Amazon API Gateway+AWS Lambda) - CLOVER🍀
- LocalStack Serverless Framework | Docs
- Serverless Framework Documentation
- Serverless Frameworkのインストールやコマンドなど | Fire Sign Blog
- WSL 2 上で Node.jis を設定する | Microsoft Docs
- localstack/serverless-localstack: ⚡ Serverless plugin for running against LocalStack
- localstack/serverless-python-rest-api-with-dynamodb: Serverless CRUD service exposing a REST HTTP interface integrated with LocalStack
- AWS Deployments using Serverless and Localstack | by Tony Tannous | Medium
Discussion