Amazon Web Services ブログ
Amazon DocumentDB を使って AWS Lambda ベースのアプリケーションを実行する
スケーラブルなアプリケーションを構築するときは、マイクロサービスベースのアプリケーションアーキテクチャを使うのが標準となっています。AWS が提供する Amazon DocumentDB (MongoDB 互換) を利用すると、こうしたタイプのアプリケーションの作成がこれまでよりもさらに容易になります。MongoDB のワークロードをサポートしている、この高速でスケーラブル、かつ可用性に優れたフルマネージド型のドキュメントデータベースサービスでは、ご自分のコードを用いてアプリケーションをデプロイするだけです。
Amazon DocumentDB でのワークロードの実行、管理、スケーリングには、現在使用している MongoDB 向けのアプリケーションコード、ドライバー、ツールをそのまま使用できます。これにより、基盤となるインフラストラクチャの管理に煩わされることなく、向上したパフォーマンス、スケーラビリティ、アベイラビリティを活用できます。
この記事では、2019 年 4 月 26 日の映画「アベンジャーズ/エンドゲーム」公開時に主要なイベントや観客の反応を確認するアプリケーションをどう構築するか、その方法について解説します。AWS Lambda アプリケーションを設定および接続し、Amazon DocumentDB にクエリを実行する際のベストプラクティスを学べます。AWS Secrets Manager と Amazon API Gateway も使用します。
概要
買い物サイトやオンラインパブリケーションは、コンテンツやカタログの管理システムに依存しながら顧客にサービスを提供しています。こうしたシステムは、ユーザーレビュー、画像、評価、製品情報、コメントに迅速かつ確実にアクセスできる必要があります。Amazon DocumentDB が提供している柔軟なドキュメントモデル、データタイプ、インデックス作成、そして、強力かつ複雑なクエリを実行できる能力は、すばやく直感的な、コンテンツの保存や発見を可能にします。
この記事のユースケースでは、Global Database of Events, Language and Tone (GDELT) の公開されているデータセットをサンプルとして使用します。GDELT Project は、「世界中のあらゆる国のほぼ全地域における、100 を超える言語の放送、出版、ウェブニュースを監視し、人、場所、組織、テーマ、情報源、反応、回数、引用、画像、イベントを特定しています」
アプリケーションの構築には、次の AWS のサービスを使用します。
- Lambda – サーバーをプロビジョンまたは管理しなくても、コードの実行を可能にするサービスです。料金は、コンピューティング使用時間に対してのみ発生します。コードが実行されていなければ無料です。
- API Gateway – API をどんなスケールでも簡単に作成、発行、保守、監視、セキュア化できるフルマネージド型のサービスです。AWS マネジメントコンソールを数回クリックするだけで REST および WebSocket API を作成できます。これらは、アプリケーションがバックエンドサービスから次のようなデータ、ビジネスロジック、または機能にアクセスするときの “フロントドア” として機能します。
- Amazon EC2 で実行中のワークロード
- Lambda で実行中のコード
- ウェブアプリケーション
- リアルタイム通信アプリケーション
- Secrets Manager – アプリケーション、サービス、IT リソースへのアクセスに必要とされる、シークレットの保護を支援するサービスです。データベースの認証情報、API キー、その他のシークレットを、それらのライフサイクルを通じて簡単にローテーション、管理、および取得することができます。ユーザーとアプリケーションは、Secrets Manager API を呼び出してシークレットを取得するので、機密情報をプレーンテキストでハードコーディングする必要はありません。
他にも、サーバーレスアプリケーションをクラウド上で簡単に構築し実行できるサービスがいくつかあります。詳細については、サーバーレスアーキテクチャを参照してください。
チュートリアル
まず、AWS CloudFormation テンプレートを使って、この記事で使用する、必要なすべてのリソースと AWS SAM テンプレートをプロビジョンします。コードは amazon-documentdb-serverless-samples GitHub リポジトリにあります。
この記事で紹介するソリューションには、次のタスクが含まれます。
- AWS CloudFormation を起動して VPC にリソースを作成します。これには、Amazon DocumentDB、Amazon VPC、AWS Cloud9 が含まれます。
– Amazon VPC を使用すると、定義した仮想ネットワークで AWS リソースを起動できます。
– AWS Cloud9 はクラウドベースの統合開発環境 (IDE) で、ブラウザのみでコードの記述、実行、およびデバッグを行えます。このサービスには、今回の演習の実行に必要な、ほぼすべてのツールと環境が装備されています。 - Amazon DocumentDB で、How to rotate Amazon DocumentDB and Amazon Redshift credentials in AWS Secrets Manager に記されているとおりに Secrets Manager の統合をセットアップします。
- AWS Cloud9 環境にログインし、コードのパッケージとライブラリを GitHub からダウンロードします。
- PyMongo ライブラリをダウンロードし、Lambda レイヤーをセットアップします。
- サンプルの GDELT データセットを、AWS パブリックデータレジストリから Amazon DocumentDB へロードします。
- API Gateway と Lambda AWS SAM テンプレートをデプロイし、AWS リソースをプロビジョンします。
- API Gateway にアクセスし、Amazon DocumentDB に対してサンプルのクエリを実行します。
AWS CloudFormation は、データを Amazon DocumentDB にロードする際に必要となる基本の環境を作成し、その後、Lambda 関数と API Gateway コードを確認しデプロイします。主な手順は次の 2 つです。
GDELT データを処理し、ドキュメントデータベースにロードする
- Lambda 関数と API Gateway API を作成して、ドキュメントデータベースに対してクエリを実行します。
GDELT データを処理し Amazon DocumentDB にロードする
このステップでは下図のアクションが行われます。
- Python のプログラムが GDELT のサイトからイベントデータを取得します。このデータセットは圧縮された CSV 形式です
- データが解凍され、行ごとに解析された後、各行が、Amazon DocumentDB テーブルに保存されている JSON ドキュメント構造に変換されます
- データが、Amazon DocumentDB にバッチで送信されます。変換後、サンプルの JSON ドキュメントは次のようなコードになります
Lambda 関数と API Gateway を作成し Amazon DocumentDB に対してクエリを実行する
この記事では、Amazon DocumentDB に保存された GDELT データをクエリするとき、Lambda プロキシ統合による API Gateway を使用して Amazon DocumentDB データベースをクエリします。続いて、クエリ文字列を GET または POST メソッドとして渡し、これを Lambda 関数の内部で処理します。こうすると、Amazon DocumentDB を検索してさまざまなユースケースに役立てることができます。
Lambda 関数は、Amazon DocumentDB にアクセスするために VPC にデプロイされます。認証情報は Secrets Manager に保存します。Secrets Manager は、さまざまなサービス (Amazon DocumentDB を含む) のパスワード等、機密情報の保存や取得に活用できます。Lambda 関数は、VPC インターフェイスのエンドポイントを使って、Amazon DocumentDB の認証情報にアクセスしたり、Secrets Manager からこの認証情報を取得したりします。
前提条件
このソリューションを完成させるためには、以下が必要です。
- イベントや映画の最新トレンドを紹介しているオンラインパブリケーションウェブサイト。この情報を JSON ドキュメントとして Amazon DocumentDB に保存することができます。また、Lambda にホストされたアプリケーションから豊富なクエリセットを実行できます。
- この記事で必要となるサービスにアクセスできる AWS アカウント。以下のステップは、米国西部 (オレゴン) リージョンで実行されます。作業を開始する前に、この記事で使用する各サービスが、ご利用の AWS リージョンで提供されていることを確認してください。
- この記事のリソースをプロビジョンおよび管理するための IAM のアクセス許可。
- Amazon DocumentDB、Amazon VPC、Lambda、AWS CloudFormation に関する実践的知識。
ステップ
以下のセクションで、本ソリューションを作成し設定するために必要なステップについて説明していきます。
ステップ 1: AWS CloudFormation テンプレートを起動する
プライベートとパブリックの 2 つのサブネットを持つ VPC、AWS Cloud9 環境、Secrets Manager の VPC エンドポイント、VPC に 1 つのインスタンスがある Amazon DocumentDB クラスターをプロビジョンします。
- この GitHub から AWS CloudFormation テンプレートをコピーまたはダウンロードします。
- AWS CloudFormation コンソールで、[スタックの作成] を選択します。
- 事前に作成した JSON ファイルをアップロードして、テンプレートを起動します。
- パラメータ値を指定します。まずはスタック名を入力します。たとえば、DocDBstack、DBClusterName、DBInstanceName、Master User、MasterPassword、DBInstanceClass など。
- 残りのパラメータ値は任意です。デフォルト設定のままにしておくこともできます。
- [次へ]、[スタックの作成] を選択します。
注意
AWS CloudFormation スタックの作成には 10~15 分かかります。Amazon DocumentDB マスターユーザーのパスワードと、AWS CloudFormation の出力セクションにあるクラスターエンドポイント、VpcId、SecurityGroupId、SubnetId 値の各値を書き留めておきます。これらは後のステップで使用します。
ステップ 2: Amazon DocumentDB で Secrets Manager の統合をセットアップする
Amazon DocumentDB マスターユーザーとパスワードの新しいシークレットを作成します。How to rotate Amazon DocumentDB and Amazon Redshift credentials in AWS Secrets Manager の “Phase 1” までのステップに従います。
次のスクリーンショットは、シークレットを作成した後の画面です。[シークレットの名前] を書き留めておきます。これは、サーバーレスアプリケーションを設定する際に使用します。
Amazon DocumentDB は、アプリケーションが同じ VPC で実行されることを要求します。つまり Lambda 関数は VPC 設定でデプロイするということです。ベストプラクティスとして、VPC インターフェイスエンドポイントを使って Secrets Manager に接続し、Amazon DocumentDB の認証情報を取得します。Secrets Manager の VPC エンドポイントを設定する方法の詳細については、How to connect to AWS Secrets Manager service within a Virtual Private Cloud を参照してください。この記事では、VPC エンドポイントは AWS CloudFormation スタックの一部として事前設定されています。
ステップ 3: AWS Cloud9 環境にログインし環境をセットアップする
ソリューションの設定とデプロイには、AWS Cloud9 環境を使用します。
AWS Cloud9 コンソールの [AWS CloudFormation Outputs] で、AWS Cloud9 URL を取得します。そして、ログインします。
$ sudo su - #login to root
次のコマンドを使って、amazon-documentdb-serverless-samples GitHub リポジトリからパッケージをクローン化します。
# git clone
https://github.com/aws-samples/amazon-documentdb-serverless-samples.git
# cd amazon-documentdb-serverless-samples
送信中のデータを暗号化するには、Amazon DocumentDB の公開キーを以下のようにダウンロードします。これをルートフォルダ (/root/amazon-documentdb-serverless-samples) に入れます。
# wget
https://s3.amazonaws.com/rds-downloads/rds-combined-ca-bundle.pem
リポジトリのファイル構造は、次のスクリーンショットのようになります。
このルートフォルダは、お使いの環境のルートフォルダです。このフォルダは、Git リポジトリのクローンを作成した場所に応じて異なる場合があります。
Gdelt_data フォルダは、GDELTDataParser ファイルを実行したときに作成されます。
Sam-app フォルダには、Lambda 関数をアップロードするために必要なリソースを作成する Lambda 関数 のためのアプリケーションファイルが保管されています。
Tests フォルダは、sam init
コマンドを使用したときに、デフォルトで作成されます。
ステップ 4: PyMongo ライブラリをダウンロードし Lambda レイヤーをセットアップする
Lambda 関数から Amazon DocumentDB に接続するときは、PyMongo ドライバーを使用します。これは、Apache License 2.0 の下でライセンスを付与されています。Lambda レイヤーの機能を使ってこのドライバーをアップロードし Lambda 関数で使用します。これにより、依存関係をより効果的に管理できるようになります。
AWS Cloud9 環境で次のステップを実行します。
- PyMongo ドライバーを AWS Cloud9 環境にインストールし、これをパッケージ化して Lambda レイヤーとしてアップロードします。
$ sudo su -
# pip install pymongo
# cd /tmp/
# mkdir pymongolayer
# cd pymongolayer/
- Python レイヤーに必要なフォルダ構造を、以下の通りに作成します (エクスポート変数を使ってこのレイヤーを再利用する)。
# export LAYER=python/lib/python3.6/site-packages
# pip install -t $LAYER pymongo==3.6
# zip –r pymongolayer.zip *
- pymongolayer.zip ファイルを Amazon S3 バケットにコピーして「AWS Lambda レイヤー」の指示に従った後、Lambda レイヤーとしてエクスポートします。下記の aws lambda publish-layer-version コマンドを使用するか、コンソールを使用します。
このコマンドを実行する前に、aws configure を使って CLI 環境を設定します。
#aws lambda publish-layer-version --layer-name pymongolayer --description "DocumentDB Python connectivity" --license-info "MIT" \
--content S3Bucket=<bucketname>,S3Key=pymongolayer.zip --compatible-runtimes python2.7 python3.6
コンソールから、または Lambda list-layers コマンドを使って、Lambda レイヤーの ARN を書き留めます。これは、ステップ 6 でサーバーレスアプリケーションの作成に必要な template.yaml ファイルを設定する際に使用します。
ステップ 5: GDELT のサンプルのデータセットを Amazon DocumentDB にロードする
GDELT データを JSON ドキュメントとして Amazon DocumentDB にロードします。設定の詳細が正しく入力されていることを確認します。
スクリプトを実行してロードを開始する前に、ダウンロードしたソースコードで、次のファイルを編集し、プロパティをアップデートします。
/gdelt_parse_config.properties
このファイルには、データを取得してドキュメントデータベースにロードするための、必要なプロパティが含まれています。これは設定ファイルで、以下の通りにアップデートする必要があります。
例として、2019 年 4 月 26 日の GDELT データをダウンロードします。必要に応じて、日付を変更してデータをロードできます。
次の Python ファイル、GDELTDataParser.py を実行し、サンプルのデータセットを GDELT から Amazon DocumentDB へロードします。このアクションにより、GDELT_DB という名前の、コレクション GDELT_COLL をもつ新しいデータベースが作成され、データがこのコレクションにロードされます。
#python GDELTDataParser.py
データのロードが正常に完了したことを確認します。接続と、ドキュメントデータベースに対するクエリの実行には、Mongo シェルを使用できます。Mongo シェルの設定に関する詳細は、「ステップ 3: mongo シェルを使用して Amazon DocumentDB クラスターにアクセスして使用する」を参照してください。クイックリファレンスには、次のサンプルのコマンドを使用します。
rs0:PRIMARY> Show dbs;
rs0:PRIMARY> use GDELT_DB;
rs0:PRIMARY> Show collections;
rs0:PRIMARY> db.GDELT_COLL.count();
または、DocumentDBActions.py ファイルを使って queryTest() 呼び出しのコメントを解除し、コンソールに表示されたデータを確認します。このデータは、GDELT データを取得するのにどの日付を選択したかによって、異なります。
データロードのスクリプトをすでに実行済みで、最初から開始したいときは、ドキュメントデータベースのデータを先に削除しておきます。その後、Amazon DocumentDB DML コマンドまたは提供されている DocumentDBActions.py ファイルを使って、次の手順を実行します。
- ファイルの最後まで進み、cleanupDb() メソッドのコメントを解除して、それ以外にコメントを付けます。
- この Python ファイルを、次のコマンドを使って保存し実行します。
#python DocumentDBActions.py
ステップ 6: AWS SAM テンプレートをデプロイしてサーバーレスアプリケーションをプロビジョンする
このステップでは、AWS SAM テンプレートを使ってサーバーレスアプリケーションをデプロイします。AWS SAM テンプレートファイルは、オープンソースの AWS SAM 仕様に従う YAML または JSON の設定ファイルです。このテンプレートを使って、サーバーレスアプリケーションを構成しているすべての AWS リソースを宣言します。
サーバーレスアプリケーションの AWS SAM テンプレートをデプロイします。
- お使いの AWS Cloud9 環境で、sam-app フォルダ (/root/amazon-documentdb-serverless-samples/sam-app/) に進みます。
- 次のコマンドを入力します。
#Cd document_db_app
送信中のデータを暗号化するには、Amazon DocumentDB の以下の公開キーをダウンロードします。これをルートフォルダ (/root/amazon-documentdb-serverless-samples/sam-app/document_db_app) に入れます。この pem ファイルはパッケージ化され、サーバーレスアプリケーションの一部としてデプロイされます。
# wget
https://s3.amazonaws.com/rds-downloads/rds-combined-ca-bundle.pem.
../sam_app フォルダに戻ります。template.yaml を開き、以下を編集します (シークレット、VPC、レイヤー情報)。
パラメータ:
以上の変更を行ったら、AWS Cloud9 シェルで次のコマンドを呼び出します。
#sam Validate
マークアップはインデントの影響を受けるので、このテンプレートが有効であることを確認します。確認したら、次のコマンドを実行してサーバーレスアプリケーションをパッケージ化します。
# sam package --s3-bucket <s3 bucketname> --output-template-file packaged.yaml
# sam deploy --template-file packaged.yaml --stack-name docdb-serverlessapp-v1 --capabilities CAPABILITY_IAM
S3 バケットは、AWS SAM テンプレートのデプロイリージョンと同じリージョンに置かれていなければなりません。既存の S3 バケットがない場合は、上記のコマンドを実行する前に、新規バケットを作成しておきます。
AWS SAM のデプロイにより、AWS CloudFormation スタックが、Lambda 関数、IAM ロール、Lambda プロキシ統合による API Gateway、によってプロビジョンされます。スタックが正常に作成されたことを確認したら、次のステップに進みます。
ステップ 7: API Gateway にアクセスし Amazon DocumentDB にサンプルのクエリを実行する
ここでは例を示すために、Lambda 関数を、ドキュメントデータベースにクエリを行い、言及の最大数、イベントの合計数、最も話題になったイベント、といったカテゴリに基づいて情報を提供するように設計します。クエリの引数は API Gateway エンドポイントを使用して渡します。それによって Lambda 関数を呼び出し、情報を取得します。
以上を行うには、API Gateway に組み込まれているシンプルなテスト機能を使用するか、次の手順に従います。
- API Gateway コンソールを開き、今回のデプロイの一部として作成された DocumentDBQueryExample API を見つけます。
- [ステージ]、[Demo stage] へ進みます (デフォルトのステージは無視します)。
- [テスト] を選択します。
このデモは、GET と POST の両方のメソッドをサポートしています。GET メソッドでは、クエリパラメータを送信します。POST メソッドでは、body を使って同じパラメータを送信します。必ず、後ほど記述する値と同じ値を送信します。POST メソッドを使用すると、より簡単に、複雑なクエリをドキュメントデータベースに実装できます。
ユースケース 1: クエリを実行してその日言及が最も多かった記事を検索する (メソッド: GET)
その日言及が最も多かった記事でこの関数をテストするには、GET メソッドのステージ URL をコピーします。ブラウザを開き、その URL を次のようなクエリパラメータと共に呼び出します。
https://<API URL from the stage Demo>/demo?dbquery=most talked event
ブラウザには次のような応答が返るはずです。
Most mentioned article (4398 Times) was https://www.washtimesherald.com/news/national_news/quarantines-at-la-universities-amid-us-measles-outbreak/article_86fa321a-b81c-58f1-9d55-91c67f70bde5.html
ユースケース 2: クエリを実行してイベントの合計数または最も話題になったイベントを検索する (メソッド: POST)
イベントの合計数でこの関数をテストするには、次のコマンドを関数の body に渡します。
{
"dbquery" : "total number of events"
}
応答:
Total number of events for the day reported 178000
最も話題になったイベントでこの関数をテストするには、次のコマンドを関数の body に渡します。
{
"dbquery" : "Most Talked Event"
}
応答:
Most mentioned article (4398 times) was https://www.washtimesherald.com/news/national_news/quarantines-at-la-universities-amid-us-measles-outbreak/article_86fa321a-b81c-58f1-9d55-91c67f70bde5.html
ユースケース 3: クエリを実行して「アベンジャーズ/エンドゲーム」の合計言及数を検索する (メソッド: POST)
イベントの合計言及数でこの関数をテストするには、次のコマンドを関数の body に渡します。
{
"dbquery" : "number of mentions {avengers}"
}
応答:
Avengers Endgame was mentioned 300 times
クリーンアップ
今後請求を発生させないようにするため、次の AWS リソースを削除します。
- ステップ 1 で作成した AWS CloudFormation スタック
- ステップ 2 で作成したシークレット
- ステップ 7 で AWS SAM テンプレートを使って作成した AWS CloudFormation スタック
まとめ
この記事では、API Gateway と Lambda を使ってマイクロサービスベースのアプリケーションを構築、実行し、Amazon DocumentDB に接続する方法をご紹介しました。また、GDELT データセットとコードを使って CSV データセットをダウンロードし、JSON ドキュメントに変換して、Amazon DocumentDB に保存しました。
以下のベストプラクティスについても確認しました。
- Amazon DocumentDB 接続のセットアップ
- 認証情報の管理に必要な Secrets Manager の統合
- AWS SAM テンプレートを使用したサーバーレスアプリケーションのデプロイ
著者について
Raj Chilakapati は、アマゾン ウェブ サービスのソリューションアーキテクトです。
Gowri Balasubramanian は、アマゾン ウェブ サービスのプリンシパルデータベースソリューションアーキテクトです。