DVA

SAMでDynamoDBを使ったサーバレスアプリを構築

スポンサーリンク
SAMで構築するDynamoDBを使ったサーバーレスアプリ DVA
スポンサーリンク
スポンサーリンク

DynamoDBを使ったサーバレスアプリをSAMで構築する

AWS DVAの出題範囲の1つでもある、デプロイに関する内容です。
AWS SAM(Serverless Application Model)を使ったサーバレスアプリの作成方法を確認します。

以下のページで、SAMを使って、LambdaとAPI Gatewayを組み合わせて、サーバレスアプリの構築方法をご紹介しました。

今回はこの続編ということで、新たにDynamoDBを組み込んだサーバレスアプリを構築します。

構築する環境

AWS認定アソシエイト3資格対策~ソリューションアーキテクト、デベロッパー、SysOpsアドミニストレーター~ | 平山毅, 堀内康弘, 福垣内孝造, 岡智也, 池田大, 原江梨佳, 澤田拓也, 原俊太郎, 仲村勇亮, 上村祐輝, 鳥谷部昭寛 | 工学 | Kindleストア | Amazon
Amazonで平山毅, 堀内康弘, 福垣内孝造, 岡智也, 池田大, 原江梨佳, 澤田拓也, 原俊太郎, 仲村勇亮, 上村祐輝, 鳥谷部昭寛のAWS認定アソシエイト3資格対策~ソリューションアーキテクト、デベロッパー、SysOpsアドミニストレーター~。アマゾンならポイント還元本が多数。一度購入いただいた電子書籍は、K...
Diagram of serverless app using DynamoDB built with SAM.

基本的には、以前の構成と同様です。
API Gatewayをエンドポイント、バックエンドでLambdaとして作成します。

LambdaからDynamoDBへアクセスし、データの読み書きを実行します。
ユーザからアクセスがあった場合、その日時データを保存します。その後、保存されている全日時データをスキャンし、結果を返します。

SAMテンプレートファイル

以下の構成をSAMで作成します。
以下のURLに、SAMテンプレートとLambda関数用スクリプトファイルを配置しています。

awstut-dva/01/001 at main · awstut-an-r/awstut-dva
Contribute to awstut-an-r/awstut-dva development by creating an account on GitHub.

ポイント解説

SAMの基本的な事項については、以下のページをご確認ください。

DynamoDBの基本については、以下のページをご確認ください。

本ページでは、上記で触れられてない点について取り上げます。

LambdaからDynamoDBにアクセスするための権限

Lambda関数およびAPI Gatewayの定義は、先述のページと同様です。
ただ今回はLambdaからDynamoDBにアクセスするため、IAMロールを作成し、必要な権限を付与します。

Resources: HelloWorldFunctionRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: sts:AssumeRole Principal: Service: - lambda.amazonaws.com ManagedPolicyArns: - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole Policies: - PolicyName: HelloWorldFunctionPolicies PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - dynamodb:List* - dynamodb:DescribeReservedCapacity* - dynamodb:DescribeLimits - dynamodb:DescribeTimeToLive Resource: "*" - Effect: Allow Action: #- dynamodb:BatchGet* #- dynamodb:DescribeStream #- dynamodb:DescribeTable #- dynamodb:Get* #- dynamodb:Query - dynamodb:Scan #- dynamodb:BatchWrite* #- dynamodb:CreateTable #- dynamodb:Delete* #- dynamodb:Update* #- dynamodb:PutItem Resource: !GetAtt Table.Arn
Code language: YAML (yaml)

今回はAWS公式のAmazon DynamoDB: 特定のテーブルへのアクセスを許可するを参考にIAMロールを定義しました。

SAMでDynamoDBを定義する

SAMには、専用の記法が用意されています。
今回はSAMの記法に則って、現在日時を保存するためのDynamoDBテーブルを定義します。

Resources: Table: Type: AWS::Serverless::SimpleTable Properties: PrimaryKey: Name: dt Type: String #ProvisionedThroughput: TableName: !Sub ${Prefix}-Table
Code language: YAML (yaml)

通常のCloudFormationでは、DynamoDBを作成する場合、Typeプロパティに「AWS::DynamoDB::Table」を指定しますが、SAMの記法に従うと「AWS::Serverless::SimpleTable」となります。
PrimaryKeyプロパティでパーティションキーを指定します。今回は「dt」という文字列タイプの属性をパーティションキーとするように指定します。
今回はProvisionedThroughputプロパティを設定しません。設定しないということは、オンデマンドモードを選択するという意味になります。

ProvisionedThroughput

スループットプロビジョニング情報の読み取りと書き込み。
ProvisionedThroughput を指定しなかった場合、BillingMode は PAY_PER_REQUEST として指定されます。

AWS::Serverless::SimpleTable

なおオンデマンドモードは、事前のキャパシティプロビジョニングが不要で、トラフィック量に応じた支払いが可能なモデルです。

DynamoDB on-demandはシンプルなpay-per-request課金モデルを提供しreadリクエストとwriteリクエストを使った分に応じて支払うだけになります。これによりシンプルなコスト計算とパフォーマンス管理を実現します。

Amazon DynamoDB On-Demand – 事前のキャパシティプランニングが不要のリクエスト課金が可能になりました。

参考までに、通常のCloudFormationの記法で、同様のテーブルを作成する場合のコードを記載します。

Resources: SampleTable: Type: AWS::DynamoDB::Table Properties: AttributeDefinitions: - AttributeName: dt AttributeType: S BillingMode: PAY_PER_REQUEST KeySchema: - AttributeName: dt KeyType: HASH TableName: !Sub ${Prefix}-SampleTable
Code language: YAML (yaml)

PythonからDynamoDBにアクセスする

PythonスクリプトからDynamoDBへアクセスし、アイテムを読み書きする方法を確認します。

import json import boto3 import datetime import json TABLE_NAME = 'dva-01-001-Table' REGION_NAME = 'ap-northeast-1' def lambda_handler(event, context): now = datetime.datetime.now() now_str = now.strftime('%Y-%m-%d %H:%M:%S') dynamodb_config = { 'region_name': REGION_NAME } dynamodb = boto3.resource('dynamodb', **dynamodb_config) table = dynamodb.Table(TABLE_NAME) table.put_item(Item={ 'dt': now_str }) result = table.scan() return { "statusCode": 200, "body": json.dumps( {"AccessDatetime": result}, indent=2 ) }
Code language: Python (python)

ポイントを取り上げます。
datetimeオブジェクトを作成し、現在日時を取得します。取得後、フォーマットを指定して文字列として取得します。
boto3.resourceでBynamoDBにアクセスするためのクライアントオブジェクトを作成します。
同オブジェクトを使用し、テーブル名を指定して、テーブルオブジェクトを作成します。
テーブルオブジェクトのput_itemメソッドで項目を保存できます。今回は属性名をdtとし、先ほど取得した現在日時データを保存します。
保存済みの全項目を取得する場合は、同オブジェクトのscanメソッドを使用します。
最後にHTTPのステータスコードとともに、scanメソッドで取得したデータを返します。

SAMアプリをビルド・デプロイ

samコマンドを使用して、アプリをビルドし、デプロイします。
以下のページをご確認ください。

今回生成された主要リソースの情報は以下の通りです。

  • API Gateway:HelloWorldApi
  • Lambda関数:HelloWorldFunction
  • DynamoDB:dva-01-001-SimpleTable

AWS Management Consoleからも、リソースの作成状況を確認します。
まずCloudFormationで作成されたスタックを確認します。

The CloudFormation stack is created by SAM deployment.

SAMアプリをデプロイすることによって、自動的にCloudFormationスタックが作成されました。
これはSAMがCloudFormationの変形であるためです。

The resources defined in the SAM template are created in the stack.

Resourcesタブを見ると、実際に作成されたリソースを確認することができます。

作成されたリソースの詳細を確認します。

Lambda Function is created by SAM deployment.
DynamoDB is created by SAM deployment.
The API Gateway was created by SAM deployment.

Lambda、DynamoDB、API Gatewayが作成されました。特にAPI Gatewayに関しては、エンドポイントのURLが確認できます。

A Lambda function is associated with /hello in API Gateway.

SAMアプリにアクセス

準備が整いましたので、アプリにアクセスします。

Access to Serverless Apps 1.

応答がありました。API Gatewayを介して、Lambda関数が呼び出され、同関数内からDynamoDBにアクセスしています。
現在日時情報が1件書き込まれた後、scanが実行されていることがわかります。

何度かアクセスしてみます。

Access to Serverless Apps 2.

アクセスする度に、アイテム数が増えていくことがわかります。

最後にAWS Management ConsoleからDynamoDBを確認してみます。

DynamoDB scan results.

こちらからも保存されているアイテムが表示されました。
先ほどと同様に3件分が確認できます。

まとめ

SAMを使用して、Lambda、API Gateway、そしてDynamoDBで構成されるWebアプリの作成方法を確認しました。

タイトルとURLをコピーしました