前提
環境
今回は、Macの環境で行いますが、セットアップ方法以外の実行に際しては、Windows / Linuxでも大きな差異はないので、ご参考になるかと思います。
構成
- API Gateway
- Lambda (Python 3.7)
- DynamoDB
boto3によりDynamoDBにレコードを作成するサンプルを作成してみたいと思います。
その他必要なもの
- AWSアカウント
セットアップ
まずは、「[AWS] Serverless Application Model (SAM) の基本まとめ」にあわせてセットアップをしていきたいと思います。
- Docker Desktopをインストールする
- Dockerを起動する
$ docker -v
Docker version 19.03.12, build 48a66213fe
- Homebrewをインストールする
$ brew -v
Homebrew 2.4.8
Homebrew/homebrew-core (git revision 820df; last commit 2020-07-27)
Homebrew/homebrew-cask (git revision 35ad13; last commit 2020-07-28)
- SAM CLIをインストールする
$ brew tap aws/tap
Updating Homebrew...
==> Auto-updated Homebrew!
Updated 1 tap (homebrew/cask).
No changes to formulae.
==> Tapping aws/tap
Cloning into '/usr/local/Homebrew/Library/Taps/aws/homebrew-tap'...
remote: Enumerating objects: 20, done.
remote: Counting objects: 100% (20/20), done.
remote: Compressing objects: 100% (16/16), done.
remote: Total 654 (delta 8), reused 10 (delta 4), pack-reused 634
Receiving objects: 100% (654/654), 134.26 KiB | 384.00 KiB/s, done.
Resolving deltas: 100% (297/297), done.
Tapped 5 formulae (42 files, 208.2KB).
$ brew install aws-sam-cli
Updating Homebrew...
==> Auto-updated Homebrew!
Updated 1 tap (homebrew/core).
==> Updated Formulae
pnpm xxhash
==> Installing aws-sam-cli from aws/tap
==> Downloading https://github.com/awslabs/aws-sam-cli/releases/download/v1.0.0/
Already downloaded: /Users/******/Library/Caches/Homebrew/downloads/e6dd54932e5f527780cb97f2a3637d334e4e40bf26c83783ab6b9e7740cd568e--aws-sam-cli-1.0.0.sierra.bottle.tar.gz
==> Pouring aws-sam-cli-1.0.0.sierra.bottle.tar.gz
🍺 /usr/local/Cellar/aws-sam-cli/1.0.0: 4,109 files, 83MB
Python 3.8xがインストール済みの場合、失敗することがあります。
$ sam --version
SAM CLI, version 1.0.0
あと、AWS CLIも必要になるため、インストールされていない場合は、
$ brew install awscli
でインストールしてください。
$ aws --version
aws-cli/2.0.34 Python/3.8.5 Darwin/19.6.0
また、今回はboto3を使用するので、
$ pip install boto3
でboto3のインストールもお願いします。
SAMでアプリケーション作成
まずは HelloWorld から
プロジェクトの作成
まずは、作業用のディレクトリを用意します。
$ mkdir samapp
$ cd samapp
Pythonの環境も仮想環境にしておきましょうか。
$ python -m venv venv
$ . ./venv/bin/activate
では、さっそく雛形を作成していきましょう。
$ sam init --runtime python3.7
Which template source would you like to use?
1 - AWS Quick Start Templates
2 - Custom Template Location
Choice: 1
Project name [sam-app]:
Cloning app templates from https://github.com/awslabs/aws-sam-cli-app-templates.git
AWS quick start application templates:
1 - Hello World Example
2 - EventBridge Hello World
3 - EventBridge App from scratch (100+ Event Schemas)
4 - Step Functions Sample App (Stock Trader)
5 - Elastic File System Sample App
Template selection: 1
-----------------------
Generating application:
-----------------------
Name: sam-app
Runtime: python3.7
Dependency Manager: pip
Application Template: hello-world
Output Directory: .
Next steps can be found in the README file at ./sam-app/README.md
途中で入力が必要な箇所がありますが、まずはオーソドックスに、
- Template source: AWS Quick Start Templates
- Project Name : sam-app
- Template : Hello World Example
としておきます。
ビルド
sam init
で、プロジェクト名のディレクトリが作成されます。今回はデフォルトのままsam-app
を指定しましたので、プロジェクトディレクトリに移動してから、ビルドを実行します。
$ cd sam-app/
$ sam build
Building function 'HelloWorldFunction'
Running PythonPipBuilder:ResolveDependencies
Running PythonPipBuilder:CopySource
Build Succeeded
Built Artifacts : .aws-sam/build
Built Template : .aws-sam/build/template.yaml
Commands you can use next
=========================
[*] Invoke Function: sam local invoke
[*] Deploy: sam deploy --guided
実行
ローカルで動作させるためには、Dockerが動作している必要があります。
もし、Dockerのエンジンが起動されていない場合は、起動しておいてください。
$ sam local start-api
Mounting HelloWorldFunction at http://127.0.0.1:3000/hello [GET]
You can now browse to the above endpoints to invoke your functions. You do not need to restart/reload SAM CLI while working on your functions, changes will be reflected instantly/automatically. You only need to restart SAM CLI if you update your AWS SAM template
2020-07-28 11:54:52 * Running on http://127.0.0.1:3000/ (Press CTRL+C to quit)
これで起動している状態なので、ブラウザでhttp://127.0.0.1:3000/hello
にアクセスしてみましょう。
初回は、準備等が実行されるので、少し時間がかかりますが、少し待つと、ブラウザに
{"message": "hello world"}
と表示されるかと思います。これで、ローカル環境のDocker上の仮装的なLambda環境が動作していることが確認できたと思います。
この状態で、コンソールで「Ctrl+C」でdockerコンテナが停止しましょう。
リファクタリング
コードディレクトリ名の変更
では、現在「HelloWorld」用に構成されているアプリケーションを少しいじってみましょう。
まずは。プロジェクト配下にあるディレクトリ名を変更したいと思います。
現在「hello_world」というディレクトリができているので、これを「sam_ddb」に変更してみることにしましょう。
$ mv hello_world sam_ddb
template.ymlの変更
SAMの定義でもあるテンプレートを修正します。
ここでは、「hello_world」
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
sam-app
Sample SAM Template for sam-app
# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
Function:
Timeout: 3
Resources:
HelloWorldFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: hello_world/
Handler: app.lambda_handler
Runtime: python3.8
Events:
HelloWorld:
Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
Path: /hello
Method: get
Outputs:
# ServerlessRestApi is an implicit API created out of Events key under Serverless::Function
# Find out more about other implicit resources you can reference within SAM
# https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api
HelloWorldApi:
Description: "API Gateway endpoint URL for Prod stage for Hello World function"
Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello/"
HelloWorldFunction:
Description: "Hello World Lambda Function ARN"
Value: !GetAtt HelloWorldFunction.Arn
HelloWorldFunctionIamRole:
Description: "Implicit IAM Role created for Hello World function"
Value: !GetAtt HelloWorldFunctionRole.Arn
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
sam-app
Sample SAM Template for sam-app
# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
Function:
Timeout: 30
Resources:
SamDdbFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: sam_ddb/
Handler: app.lambda_handler
Runtime: python3.8
Events:
SamDdb:
Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
Path: /ddb
Method: get
Outputs:
# ServerlessRestApi is an implicit API created out of Events key under Serverless::Function
# Find out more about other implicit resources you can reference within SAM
# https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api
SamDdbApi:
Description: "API Gateway endpoint URL for Prod stage for SAM DDB function"
Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/ddb/"
SamDdbFunction:
Description: "SAM DDB Lambda Function ARN"
Value: !GetAtt SamDdbFunction.Arn
SamDdbFunctionIamRole:
Description: "Implicit IAM Role created for SAM DDB function"
Value: !GetAtt SamDdbFunctionRole.Arn
テストコード
今回は使用しませんが、ついでにテスト用のコードも修正してしまいましょう。
5行目を以下のように修正します。
from hello_world import app
from sam_ddb import app
ビルド
この段階で、一度ビルドしてみましょう。
$ sam build
Building function 'SamDdbFunction'
Running PythonPipBuilder:ResolveDependencies
Running PythonPipBuilder:CopySource
Build Succeeded
Built Artifacts : .aws-sam/build
Built Template : .aws-sam/build/template.yaml
Commands you can use next
=========================
[*] Invoke Function: sam local invoke
[*] Deploy: sam deploy --guided
Building functionが変更されていることが確認できると思います。
実行
では、先ほど同様、ローカルで実行してみましょう。
$ sam local start-api
Mounting SamDdbFunction at http://127.0.0.1:3000/ddb [GET]
You can now browse to the above endpoints to invoke your functions. You do not need to restart/reload SAM CLI while working on your functions, changes will be reflected instantly/automatically. You only need to restart SAM CLI if you update your AWS SAM template
2020-07-28 13:29:59 * Running on http://127.0.0.1:3000/ (Press CTRL+C to quit)
こちらも成功し、URLがhttp://127.0.0.1:3000/ddb
に変わっていることが確認できるかと思います。
そして、http://127.0.0.1:3000/ddb
にブラウザでアクセスして、先ほどと同じ結果になることを確認しましょう。
ローカルにDynamoDBの環境を構築してみる
次は、DynamoDBへのアクセスですが、AWS上にプロビジョニングする前に、ローカルでLambda関数のテストを行うために、ローカルにDynamoDBの環境を作る必要があります。
テーブル定義
まずは、テーブルの構造をJsonファイルで定義します。
下記内容を格納するディレクトリとして、プロジェクトのディレクトリ直下に「ddb」というディレクトリを作成してください。
その中に「ddb.json」というファイル名で、下記内容のファイルを作成してみましょう。
{
"TableName": "Demo",
"KeySchema": [
{
"AttributeName": "Key",
"KeyType": "HASH"
},
{
"AttributeName": "CreateDate",
"KeyType": "RANGE"
}
],
"AttributeDefinitions": [
{
"AttributeName": "Key",
"AttributeType": "S"
},
{
"AttributeName": "CreateDate",
"AttributeType": "S"
}
],
"ProvisionedThroughput": {
"ReadCapacityUnits": 5,
"WriteCapacityUnits": 5
}
}
Lambdaの修正
では、現在「hello world」というJsonデータを返すだけのLambdaで、DynamoDBにレコードを登録するような実装に変更してみましょう。
今回は、POSTリクエストに渡された「key」に指定された内容をDynamoDBに登録するサンプルにしたいと思います。
CreateDateは、現在日時を取得して格納します。
以下が、書き換え後のサンプルコードです。
import json
import boto3
import os
from datetime import datetime
def lambda_handler(event, context):
try:
event_body = json.loads(event["body"])
if "local" in event_body and event_body["local"] == True:
dynamodb = boto3.resource("dynamodb", endpoint_url="http://dynamodb:8000")
else:
dynamodb = boto3.resource("dynamodb")
table = dynamodb.Table("Demo")
table.put_item(
Item={
"Key": event_body["key"],
"CreateDate": datetime.utcnow().isoformat()
}
)
return {
"statusCode": 200,
"body": json.dumps({
"message": "succeeded",
}),
}
except Exception as e:
return {
"statusCode": 500,
"body": json.dumps({
"message": e.args
}),
}
定義の修正
まず、Pythonでboto3を使用するためrequirements.txt
に「boto3」を追記し、以下のような内容に修正します。
requests
boto3
そして、SAMのテンプレートも、少しだけ修正を加えます。
25行目
Method: get
Method: post
DynamoDBを起動する
ローカルでのDynamoDBはDockerコンテナで動作させることができます。
以下での手順でDockerコンテナを起動するところまで実行してみましょう。
$ docker pull amazon/dynamodb-local
Using default tag: latest
latest: Pulling from amazon/dynamodb-local
638b75f800bf: Pull complete
a455ee0c5c58: Pull complete
c7e215ba3460: Pull complete
Digest: sha256:c8aeb014edfff8b93d7f14054cb9d2a1be214d62b7c5b61eb7fb40893a8404bb
Status: Downloaded newer image for amazon/dynamodb-local:latest
docker.io/amazon/dynamodb-local:latest
$ docker network create ddb-network
5c81f9e8f32413cfcf9aec4d4165d6f53cee67d167ad87d2e99813b90219c422
$ docker run --network ddb-network --name dynamodb -p 8000:8000 amazon/dynamodb-local -jar DynamoDBLocal.jar -sharedDb
Initializing DynamoDB Local with the following configuration:
Port: 8000
InMemory: false
DbPath: null
SharedDb: true
shouldDelayTransientStatuses: false
CorsParams: *
この状態で一度「Ctrl+C」でコンテナを停止し、
$ docker start dynamodb
を実行してください。バックグランドでDynamoDBが起動されます。
ローカルDynamoDBにテーブル定義を追加する
現在起動しているローカルのDynamoDBにはテーブルの定義がありませんので、先ほど「ddb/ddb.json」で定義した内容でテーブルを作成したいと思います。
$ aws dynamodb create-table --cli-input-json file://./ddb/ddb.json --endpoint-url http://localhost:8000
これで、ローカルのDynamoDBに、テーブルが作成されました。
ビルド
では、例によって、ビルドを実行したいと思います。
$ sam build
Building function 'SamDdbFunction'
Running PythonPipBuilder:ResolveDependencies
Running PythonPipBuilder:CopySource
Build Succeeded
Built Artifacts : .aws-sam/build
Built Template : .aws-sam/build/template.yaml
Commands you can use next
=========================
[*] Invoke Function: sam local invoke
[*] Deploy: sam deploy --guided
実行
では、さっそく実行してみます。
今回は、ローカルのDynamoDBのコンテナと通信するために、--docker-netork
オプションが必要になるので注意してください。
$ sam local start-api --docker-network ddb-network
Mounting SamDdbFunction at http://127.0.0.1:3000/ddb [POST]
You can now browse to the above endpoints to invoke your functions. You do not need to restart/reload SAM CLI while working on your functions, changes will be reflected instantly/automatically. You only need to restart SAM CLI if you update your AWS SAM template
2020-07-28 15:20:35 * Running on http://127.0.0.1:3000/ (Press CTRL+C to quit)
起動できましたね。
今度は、前回と違って「POST」でアクセスする必要があります。
したがって、今回はブラウザではなく、curl
でアクセスしてみたいと思います。
$ curl -X POST -H "Content-Type: application/json" -d '{"key": "demo-data", "local": true}' http://127.0.0.1:3000/ddb
この実行の結果
{"message": "succeeded"}
が表示されると、成功です。
DB確認
では、実際にデータがDynamoDBに登録できたかを確認してみましょう。
$ aws dynamodb scan --table-name Demo --endpoint-url http://localhost:8000
{
"Items": [
{
"CreateDate": {
"S": "2020-07-28T06:23:33.150156"
},
"Key": {
"S": "demo-data"
}
}
],
"Count": 1,
"ScannedCount": 1,
"ConsumedCapacity": null
}
これでLambda関数でのDynamoDBへのデータ登録ができることがローカルで確認することができました。
後始末
Lambda環境は「Ctrl+C」で終了できます。
あと、DynamoDBについては、以下のコマンドで終了させてください。
$ docker stop dynamodb
$ docker rm dynamodb
AWSへのデプロイ
SAMテンプレート修正
ここまできたら、デプロイのための定義をテンプレートに記述してデプロイするだけです。
テンプレートの修正は
- Resourceの中にDynamoDBのテーブルの定義追加
- Lambda関数のIAMロールの定義追加
- Lambda関数へのIAMロール適用
が主な変更点です。
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
sam-app
Sample SAM Template for sam-app
Globals:
Function:
Timeout: 30
Resources:
DynamoTable:
Type: AWS::DynamoDB::Table
Properties:
TableName: Demo
AttributeDefinitions:
- AttributeName: Key
AttributeType: S
- AttributeName: CreateDate
AttributeType: S
KeySchema:
- AttributeName: Key
KeyType: HASH
- AttributeName: CreateDate
KeyType: RANGE
ProvisionedThroughput:
ReadCapacityUnits: 5
WriteCapacityUnits: 5
SamDdbFunction:
Type: AWS::Serverless::Function
Properties:
Role: !GetAtt SamDdbFunctionIamRole.Arn
CodeUri: sam_ddb/
Handler: app.lambda_handler
Runtime: python3.7
Events:
SamDdb:
Type: Api
Properties:
Path: /ddb
Method: post
SamDdbFunctionIamRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service:
- 'lambda.amazonaws.com'
Action:
- 'sts:AssumeRole'
ManagedPolicyArns:
- 'arn:aws:iam::aws:policy/CloudWatchLogsFullAccess'
Policies:
- PolicyName: 'SamDdbPolicy'
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- dynamodb:PutItem
Resource: !GetAtt DynamoTable.Arn
Outputs:
SamDdbApi:
Description: "API Gateway endpoint URL for Prod stage for SAM DDB function"
Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/ddb/"
AWSクレデンシャルの設定
AWSにDeployするために、クレデンシャルを設定します。
aws config
で設定してもよいですが、今回は、環境変数に設定するやり方にしたいと思います。
環境変数に設定する内容は、マネジメントコンソールのIAMより、認証情報からアクセスキーを生成します。
アクセスキーの管理(コンソール)
$ export AWS_ACCESS_KEY_ID="アクセスキーID"
$ export AWS_SECRET_ACCESS_KEY="シークレットアクセスキー"
で環境変数をコンソールに設定します。
ここまで準備ができたら、あとはビルドしてデプロイを実行するだけです。
$ sam build
Building function 'SamDdbFunction'
Running PythonPipBuilder:ResolveDependencies
Running PythonPipBuilder:CopySource
Build Succeeded
Built Artifacts : .aws-sam/build
Built Template : .aws-sam/build/template.yaml
Commands you can use next
=========================
[*] Invoke Function: sam local invoke
[*] Deploy: sam deploy --guided
続いてデプロイですが、今回は対話形式で進めたいと思います。
$ sam deploy --guided
Configuring SAM deploy
======================
Looking for samconfig.toml : Found
Reading default arguments : Success
Setting default arguments for 'sam deploy'
=========================================
Stack Name [sam-app]:
AWS Region [ap-northeast-1]:
#Shows you resources changes to be deployed and require a 'Y' to initiate deploy
Confirm changes before deploy [Y/n]: y
#SAM needs permission to be able to create roles to connect to the resources in your template
Allow SAM CLI IAM role creation [Y/n]: y
SamDdbFunction may not have authorization defined, Is this okay? [y/N]: y
Save arguments to samconfig.toml [Y/n]: y
Looking for resources needed for deployment: Found!
Managed S3 bucket: aws-sam-cli-managed-default-samclisourcebucket-pqa3p7mrbwhc
A different default S3 bucket can be set in samconfig.toml
Deploying with following values
===============================
Stack name : sam-app
Region : ap-northeast-1
Confirm changeset : True
Deployment s3 bucket : aws-sam-cli-managed-default-samclisourcebucket-pqa3p7mrbwhc
Capabilities : ["CAPABILITY_IAM"]
Parameter overrides : {}
Initiating deployment
=====================
Saved arguments to config file
Running 'sam deploy' for future deployments will use the parameters saved above.
The above parameters can be changed by modifying samconfig.toml
Learn more about samconfig.toml syntax at
https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-config.html
Deploying with following values
===============================
Stack name : sam-app
Region : ap-northeast-1
Confirm changeset : True
Deployment s3 bucket : aws-sam-cli-managed-default-samclisourcebucket-pqa3p7mrbwhc
Capabilities : ["CAPABILITY_IAM"]
Parameter overrides : {}
Initiating deployment
=====================
SamDdbFunction may not have authorization defined.
Uploading to sam-app/c72e0b0797684ec987c82c67edd96573.template 1949 / 1949.0 (100.00%)
Waiting for changeset to be created..
CloudFormation stack changeset
------------------------------------------------------------------------------------------------
Operation LogicalResourceId ResourceType
------------------------------------------------------------------------------------------------
+ Add DynamoTable AWS::DynamoDB::Table
+ Add SamDdbFunctionIamRole AWS::IAM::Role
+ Add SamDdbFunctionSamDdbPermission AWS::Lambda::Permission
Prod
+ Add SamDdbFunction AWS::Lambda::Function
+ Add ServerlessRestApiDeploymentd34 AWS::ApiGateway::Deployment
ff828b5
+ Add ServerlessRestApiProdStage AWS::ApiGateway::Stage
+ Add ServerlessRestApi AWS::ApiGateway::RestApi
------------------------------------------------------------------------------------------------
Changeset created successfully. arn:aws:cloudformation:ap-northeast-1:703609122166:changeSet/samcli-deploy1595922824/c5c5c271-c3f7-4ffe-916f-d02a10b034d4
Previewing CloudFormation changeset before deployment
======================================================
Deploy this changeset? [y/N]: y
2020-07-28 16:53:59 - Waiting for stack create/update to complete
CloudFormation events from changeset
-------------------------------------------------------------------------------------------------
ResourceStatus ResourceType LogicalResourceId ResourceStatusReason
-------------------------------------------------------------------------------------------------
CREATE_IN_PROGRESS AWS::DynamoDB::Table DynamoTable Resource creation
Initiated
CREATE_IN_PROGRESS AWS::DynamoDB::Table DynamoTable -
CREATE_COMPLETE AWS::DynamoDB::Table DynamoTable -
CREATE_IN_PROGRESS AWS::IAM::Role SamDdbFunctionIamRole -
CREATE_IN_PROGRESS AWS::IAM::Role SamDdbFunctionIamRole Resource creation
Initiated
CREATE_COMPLETE AWS::IAM::Role SamDdbFunctionIamRole -
CREATE_IN_PROGRESS AWS::Lambda::Function SamDdbFunction -
CREATE_IN_PROGRESS AWS::Lambda::Function SamDdbFunction Resource creation
Initiated
CREATE_COMPLETE AWS::Lambda::Function SamDdbFunction -
CREATE_IN_PROGRESS AWS::ApiGateway::RestA ServerlessRestApi Resource creation
pi Initiated
CREATE_IN_PROGRESS AWS::ApiGateway::RestA ServerlessRestApi -
pi
CREATE_COMPLETE AWS::ApiGateway::RestA ServerlessRestApi -
pi
CREATE_IN_PROGRESS AWS::Lambda::Permissio SamDdbFunctionSamDdbPe -
n rmissionProd
CREATE_IN_PROGRESS AWS::ApiGateway::Deplo ServerlessRestApiDeplo -
yment ymentd34ff828b5
CREATE_IN_PROGRESS AWS::ApiGateway::Deplo ServerlessRestApiDeplo Resource creation
yment ymentd34ff828b5 Initiated
CREATE_IN_PROGRESS AWS::Lambda::Permissio SamDdbFunctionSamDdbPe Resource creation
n rmissionProd Initiated
CREATE_COMPLETE AWS::ApiGateway::Deplo ServerlessRestApiDeplo -
yment ymentd34ff828b5
CREATE_IN_PROGRESS AWS::ApiGateway::Stage ServerlessRestApiProdS -
tage
CREATE_IN_PROGRESS AWS::ApiGateway::Stage ServerlessRestApiProdS Resource creation
tage Initiated
CREATE_COMPLETE AWS::ApiGateway::Stage ServerlessRestApiProdS -
tage
CREATE_COMPLETE AWS::Lambda::Permissio SamDdbFunctionSamDdbPe -
n rmissionProd
CREATE_COMPLETE AWS::CloudFormation::S sam-app -
tack
-------------------------------------------------------------------------------------------------
CloudFormation outputs from deployed stack
-------------------------------------------------------------------------------------------------
Outputs
-------------------------------------------------------------------------------------------------
Key SamDdbApi
Description API Gateway endpoint URL for Prod stage for SAM DDB function
Value https://l6uressyl8.execute-api.ap-northeast-1.amazonaws.com/Prod/ddb/
-------------------------------------------------------------------------------------------------
Successfully created/updated stack - sam-app in ap-northeast-1
AWS Regionは、東京リージョンを指定するようにしてください。それ以外の「y/n」の質問はすべて「y」で問題ありません。
また、CloudFormationのスタック名も、他と重複しないような名前であれば特になんでもよいので、今回はデフォルトのアプリケーション名のままとしました。
実行
sam deploy
の最後に、API GatewayのURLが表示されているので、このURLに対してリクエストを発行するようにします。
$ curl -X POST -H "Content-Type: application/json" -d '{"key": "demo-data"}' https://l6uressyl8.execute-api.ap-northeast-1.amazonaws.com/Prod/ddb/
はい、成功のメッセージが返ってきました。
{"message": "succeeded"}
では、マネジメントコンソールで、DynamoDBの中身をみてみましょう。
Demoテーブルに、きちんとデータが登録できていることが確認できました。
まとめ
今回は手順を踏んで、HelloWorldのテンプレートから少しずつアプリケーションの形に変えていく形で作成してみましたが、慣れてくれば直接テンプレートを作成する方法でもできないことはないと思います。
あと、今回はテストコードについては放置しましたが、できればテストコードもきちんと対応しましょう。
SAMのテンプレートでは、複数のLambda関数を定義することもできますし、DynamoDB以外のリソース定義を行うこともできるので、Serverlessなアプリケーションを作る際には、十分実用価値があるのでは、と思います。
あと、SAMではなくCDKで同様のことを実現する「[AWS] CDKで、API Gateway + Lambda + DynamoDBなサンプルを作成してみる」も投稿しましたので、こtいらもよろしくです。
サンプルコードリポジトリ