サーバーレスシステム構築のベストプラクティス! Serverless Frameworkをもっと試してみよう! API GatewayとDynamoDB編
前回は、Serverless Frameworkのドキュメントに沿って、簡単に使い方を確かめてみました。今回は、API GatewayやDynamoDBをからめた使い方をみてみたいと思います。
- Serverless Frameworkのアップデート
- サービスの作成
- 必要なファイルを自動生成
- サービスの内容
- serverless.ymlの編集
- handler.pyの編集
- デプロイ
- 作成されたリソースの確認
- 動作確認
- まとめ
1. Serverless Frameworkのアップデート
今回の作業環境
名前 | バージョン |
---|---|
OS | OS X |
Python | 2.7.10 |
aws-cli | aws-cli/1.10.36 |
npm | 2.15.5 |
boto3 | 1.3.0 |
httpie | 0.9.6 |
1 2 |
sudo npm install -g serverless@beta |
バージョンの確認ができれば、アップデートは成功です。
1 2 3 |
serverless --version 1.0.0-beta.2 |
※前回のクレデンシャル情報の設定では触れていませんでしたが、公式のドキュメントには、作業するユーザーに「AdministratorAccess」権限を付与するように書かれています。Serverless Frameworkは開発途中で、まだ必要な権限が定まらないと書かれているので、今回はいったん指示通り「AdministratorAccess」権限を付与してから作業しましょう。
2. サービスの作成
アップデートできたら、次はサービスを作成します。今回は「こけし」の「工人さん」をデータベースに登録するサービスを作りたいと思います。 サービスの作成といってもやることは、サービス用のディレクトリを作成後、そのディレクトリに入るだけです。※「こけし」の場合は、作る人を「職人さん」ではなく「工人さん」と呼びます。
1 2 3 |
mkdir kokeshi-craftsmen cd kokeshi-craftsmen |
3. 必要なファイルを自動生成
以下のコマンドで必要なファイルを自動生成します。
1 2 |
serverless create --template aws-python |
前回と同様に4つのファイルが自動生成されました。
- event.json
- handler.py
- serverless.env.yml
- serverless.yml
4. サービスの内容
今回は、『API Gawayのエンドポイントにアクセスしたとき、こけし工人さんの「系統」と「名前」のデータをPUTでわたして、DynamoDBに登録する』、という流れのサービスを作りたいと思います。※「こけし」の「系統」についてはWikipediaの「伝統こけしの系統」をご確認ください。
5. serverless.ymlの編集
まずは、Serverless Frameworkのメインの設定ファイルであるserverless.ymlを編集します。serverless.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
service: kokeshi-craftsmen provider: name: aws runtime: python2.7 iamRoleStatements: - Effect: Allow Resource: "arn:aws:dynamodb:us-east-1:*:*" Action: - "dynamodb:PutItem" functions: put: handler: handler.handler events: - http: path: put method: put resources: Resources: kokeshicraftsmen: Type: "AWS::DynamoDB::Table" Properties: AttributeDefinitions: - AttributeName: type AttributeType: S - AttributeName: craftsman AttributeType: S KeySchema: - AttributeName: type KeyType: HASH - AttributeName: craftsman KeyType: RANGE ProvisionedThroughput: ReadCapacityUnits: 1 WriteCapacityUnits: 1 TableName: kokeshi_craftsmen |
serverless.ymlの説明
provider
「provider」の「iamRoleStatements」を変更して、DynamoDBにItemが追加できるようにしたいと思います。デプロイしたときに作成されるIAMロールに、ここで指定した権限が追加されます。
1 2 3 4 5 6 7 8 9 |
provider: name: aws runtime: python2.7 iamRoleStatements: - Effect: Allow Resource: "arn:aws:dynamodb:us-east-1:*:*" Action: - "dynamodb:PutItem" |
functions
「functions」でLambdaファンクションの設定とAPI Gatewayの設定をします。まず、「handler」でLambdaファンクションの設定です。「ファイル名.ファンクション名」と設定します。「events」でイベントハンドラーを設定します。API GatewayをLambdaファンクションのトリガーにしたい場合は、「-http」と設定します。S3をトリガーにしたい場合は、「- s3」といった形で設定します。「path」は、API Gatewayのエンドポイントのパス、「method」は今回は「PUT」を使うので、「put」と設定します。「GET」や「POST」を使うときはそれぞれ「get」、「post」と設定します。
1 2 3 4 5 6 7 8 |
functions: put: handler: handler.handler events: - http: path: put method: put |
resources
「resources」では、CloudFormationで作成するリソースを設定します。今回はDynamoDBのテーブル「kokeshi_craftsmen」を作成したいので、キーやカラム(アトリビュート)などの情報などをここで設定します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
resources: Resources: kokeshicraftsmen: Type: "AWS::DynamoDB::Table" Properties: AttributeDefinitions: - AttributeName: type AttributeType: S - AttributeName: craftsman AttributeType: S KeySchema: - AttributeName: type KeyType: HASH - AttributeName: craftsman KeyType: RANGE ProvisionedThroughput: ReadCapacityUnits: 1 WriteCapacityUnits: 1 TableName: kokeshi_craftsmen |
6. handler.pyの編集
次にhandler.pyの編集です。handler.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
from __future__ import print_function import json import boto3 def handler(event, context): try: if len(event['body']) == 0: return 'There is no data' body = event['body'] kokeshi_type = '' kokeshi_craftsman = '' for key, value in body.iteritems(): if key == 'type': kokeshi_type = value if key == 'craftsman': kokeshi_craftsman = value if kokeshi_type == '' or kokeshi_craftsman == '': return 'There is no Type or Craftsman' client = boto3.client('dynamodb') table_name = 'kokeshi_craftsmen' response = client.put_item( TableName = table_name, Item = { 'type': { 'S': kokeshi_type, }, 'craftsman': { 'S': kokeshi_craftsman }, } ) return response except Exception as e: return e |
handler.pyの説明
PUTでわたされたデータは「events」の「body」に入っています。PUTでデータがわたってきているかをチェックしたあと、工人さんが作っているこけしの系統のデータと工人さんの名前を、それぞれDynamoDBの「type」と「craftsman」カラム(アトリビュート)に入れる処理をおこなっています。7. デプロイ
これで設定ファイルとLambdaファンクションが完成したので、デプロイしてみましょう。
1 2 |
serverless deploy |
「Deployment successful!」とメッセージがでたら、成功です。API GatewayのエンドポイントやLambdaファンクションの「arn」が返ってきています。
8. 作成されたリソースの確認
デプロイが成功したら、想定していたリソースが問題なく作成されているか、マネジメントコンソールで確認してみましょう。CloudFormation
まずは、CloudFormationを確認します。「kokeshi-craftsmen-dev」というスタックが作成されています。CloudFormationで作成されたリソースを確認すると、LambdaファンクションやDynamoDBのテーブル、Lambdaファンクションのコードのアップロード先になるS3バケット、IAMやAPI Gatewayのリソースが作成されていることが確認できます。
IAMロール
次は、IAMロールを確認します。「kokeshi-craftsmen-dev-IamRoleLambda-XXX...」という名前のロールが作成されています。上記のロールには以下の「dev-kokeshi-craftsmen-lambda」というポリシーがひもづいています。Serverless Frameworkでデプロイしたときにデフォルトで作成されるCloudWatch Logsのポリシーと、先ほどserverless.ymlで設定したDynamoDBの「PutItem」を許可する設定がきちんとできていることがわかります。
Lambdaファンクション
次は、Lambdaファンクションです。こちらもserverless.ymlで設定したLambdaファンクションのファイル名とファンクション名の設定である「handler.handler」が設定されています。ロールには先ほど確認した「kokeshi-craftsmen-dev-IamRoleLambda-XXX...」が設定されています。API Gateway
API Gatewayも確認します。serverless.ymlで設定したエンドポイントのパス「/put」にPUTメソッドが設定されています。DynamoDB
最後にDynamoDBを確認します。serverless.ymlで設定した「type」と「craftsman」カラム(アトリビュート)をもった「kokeshi-craftsmen」テーブルが作成されています。9. 動作確認
それでは、実際に「こけし」の「工人さん」のデータをPUTしてみたいと思います。今回は「httpie」を使って簡単に確かめます。 以下のコマンドを打って、鳴子系の桜井昭寛工人のデータをDynamoDBに入れます。
1 2 3 |
http PUT https://85qlz6ddnf.execute-api.us-east-1.amazonaws.com\ /dev/put type='Naruko' craftsman='Akihiro Sakurai' |
DynamoDBのマネジメントコンソールを見ると、データが投入されています。
10. まとめ
今回は、Serverless Frameworkを使ってAPI GatewayとDynamoDBをからめたときの設定方法を試してみました。serverless.ymlに設定を書いて「serverless deploy」とコマンドを打つだけで、必要なリソースの作成ができてしまうのでとても便利ですね。
これで、こけし工人さんのデータが簡単に登録できるようになり、個人的にもとても満足です。
いや〜、Serverless Frameworkって本当にいいものですね。
COMMENT ON FACEBOOK