DynamoDBとAmazon SNSを使ったゲーム構築のチュートリアルをやってみた

DynamoDBとAmazon SNSを使ったゲーム作成チュートリアルでの備忘録です
2023.01.06

どうも。CX事業本部Delivery部のえーたん(@eetann092)です。

チュートリアルAmazon DynamoDB と Amazon SNS を使用したターン制ゲームの構築をやってみたので備忘録を残しておきます。

チュートリアルの構成

このチュートリアルでは、AWS Cloud9上で操作していきます。あらかじめ用意されたスクリプトを実行していく形式です。デプロイしたゲーム(Nim)のプレイもCloud9のターミナルでコマンドを叩いて操作します。

構成図を作ってみました。

SDKで各サービスに触れるだけではなく、Cloud9上からAWS CLIを用いてDynamoDBやSNSを操作する部分もあります。

チュートリアルの構成は以下のとおりです。

  • はじめに
  • 1 背景とセットアップ (20分)
    • AWSアカウントの作成
    • Cloud9 IDE のセットアップ
    • サポートコードのダウンロード
  • 2 データベースのプロビジョニング (30分)
    • DynamoDBデータベースのプロビジョニング
    • サンプルのゲームアイテムをテーブルに保存
    • テーブル内のゲームアイテムの更新
  • 3 通知のセットアップ (20分)
    • SNSを介したSMSメッセージの送信
  • 4 アプリケーションに認証を追加 (20分)
    • Cognito ユーザープールの作成
    • ユーザープールクライアントの作成
    • 認証コードの確認
  • 5 アプリケーションをデプロイ (20分)
    • Lambdaへのデプロイ
    • API Gateway REST API の作成と設定
    • API エンドポイントを試す
  • 6 アプリケーションを試す (20分)
    • 新規ユーザー登録
    • ログイン
    • 新規ゲーム作成
    • ゲームのステータスの取得
    • ゲーム内で行動
  • クリーンアップと次のステップ (20分)
    • リソース削除
    • Cloud9環境の削除

注意点

Lambdaのランタイムの書き換え

モジュール5「アプリケーションをデプロイ」のステップ1で作成するLambdaは、ランタイムのNode.jsのバージョンが10.xと古いため、そのまま実行すると以下のようにエラーになります。

bash scripts/create-lambda.sh
Building zip file
Creating IAM role
Adding policy to IAM role
Sleeping for IAM role propagation
Creating Lambda function

An error occurred (InvalidParameterValueException) when calling the CreateFunction operation: The runtime parameter of nodejs10.x is no longer supported for creating or updating AWS Lambda functions. We recommend you use the new runtime (nodejs16.x) while creating or updating functions.
Lambda function created with ARN

今回はscripts/create-lambda.shでのランタイムの指定をnodejs16.xに書き換え、ファイルを上書きしました。 また、すでに作成されたIAMロールCloud9-turn-based-api-lambda-roleを削除してから上書きしたスクリプトを実行しました。

scripts/create-lambda.sh

 FUNCTION_ARN=$(aws lambda create-function \
   --function-name turn-based-api \
-  --runtime nodejs10.x \
+  --runtime nodejs16.x \
   --role ${ROLE_ARN} \

環境変数の再設定

モジュール1に書いてあるとおり、チュートリアルの途中で休憩してCloud9が新しいセッションになった場合、source env.shを実行する必要があります。

SMSではなくメールにしてみた

「新しいゲームの開始」「自分のターンの開始」「ゲーム終了」で送信されるSMSメッセージを、メールにしてみました。

「3 通知のセットアップ」での変更

まず、トピックをAWS CLIで作成し、環境変数に保存します。

echo "export TOPIC_ARN=$(aws sns create-topic --region $AWS_REGION --name NimTest --output text)" >> env.sh && source env.sh

トピック名はNimTestにしました。

次に、サブスクライバーとしてメールアドレスを登録します。

aws sns subscribe --topic-arn $TOPIC_ARN --protocol email --notification-endpoint メールアドレス

上記のコマンドを実行後、承認メールが届くので承認します。

sendMessage.jsは以下のように書き換えてから実行しました。phoneNumberを削り、sns.publishのパラメータにトピックのARNを追加しています。

scripts/sendMessage.js

 const AWS = require('aws-sdk')
 const sns = new AWS.SNS();
 
-const sendMessage = async ({ phoneNumber, message }) => {
+const sendMessage = async ({ message }) => {
   const params = {
     Message: message,
-    PhoneNumber: phoneNumber
+    TopicArn: process.env.TOPIC_ARN
   }
 
   return sns.publish(params).promise()
 }
 
-sendMessage({ phoneNumber: process.env.PHONE_NUMBER, message: 'Sending a message from SNS!'})
+sendMessage({ message: 'Sending a message from SNS!'})
   .then(() => console.log('Sent message successfully'))
   .catch((error) => console.log('Error sending SNS: ', error.message))

「3 通知のセットアップ」より後のモジュールでの変更

「4 アプリケーションに認証を追加」「5 アプリケーションをデプロイ」では、Cloud9の検索でphoneNumberが出てくる箇所を削りました。

以下がゲームプレイ時に実際に送られてきたメールの例です。

プレイヤーはどちらも自分である仕様のため、勝敗も両方送られてきます。

「クリーンアップと次のステップ」での追加の処理

「クリーンアップと次のステップ」まできたら、Cloud9環境を削除する前に自分で作成したトピックも削除します。

aws sns delete-topic --topic-arn $TOPIC_ARN

感想

あらかじめ用意されたスクリプトを実行していく形式ですが、解説には関連するドキュメントや他のチュートリアルへのリンクがたくさんあり、適宜深堀りできて良かったです。リソースの削除までチュートリアルに含まれているので安心ですね。

今回はSMS→メールのように自分で書き換えた部分も勉強になりました。

最初のモジュールにあったnpm install --prefix scripts/--prefixオプションを初めて知りました。ただ、npmコマンドのhelpにはこのオプションの記述が見当たりませんでした。見つかったら追記します。

DynamoDBの条件式の比較演算子a <> bを知らなかったため、以下のドキュメントを読みました。

比較演算子および関数リファレンス - Amazon DynamoDB

Cognitoについては、チュートリアルでの解説のほか以下の2つの記事も読みました。

リンク集

最後に、もう一度チュートリアルのリンクを掲載します。

参考