AWS でのプロジェクト

モダンウェブアプリケーションを構築する

ウェブアプリケーションのデプロイ、データベースへの接続、ユーザー動作の分析

モジュール 5: ユーザー行動の把握

このモジュールでは、AWS Lambda とその他のサーバーレスサービスを使用してユーザーの行動を把握します。

概要

Mythical Mysfits サイトの立ち上げに成功しました。次に、ユーザーがウェブサイトと Mysfit とどのようにやり取りしているのかを把握する手段を作成しましょう。ユーザーが Mysfit をペットとして引き取るか、Mysfit をお気に入りに登録するとバックエンドでデータの変更が行われるため、このようなアクションをユーザーがウェブサイトで実行した場合は簡単に分析できます。

ただし、ユーザーが Mysfit をお気に入りに登録する、またはペットとして引き取る前にウェブサイトで行うアクションを理解しておくことで、ユーザーエクスペリエンスを向上させ、Mysfit をより速く引き取ってもらうことができます。このようなインサイトを収集しやすくするために、ユーザーが Mysfit のプロフィールをクリックするたびに、ウェブサイトのフロントエンドによって小さいリクエストが、これから作成する新しいマイクロサービス API に送信される機能を実装します。このレコードは、サーバーレスのコード関数によってリアルタイムで処理され、集約され、今後分析を実行できるように保存されます。

最新のアプリケーションの設計原則では、焦点を合わせた疎結合のモジュール式サービスが好まれます。このため、これまで作業してきた既存の Mysfits サービスにメソッドや機能を追加するのではなく、ユーザーのクリックイベントを Mysfits ウェブサイトから受け取るための新しい疎結合サービスを作成します。このフルスタックは、提供された CloudFormation テンプレートを使用して表されています。

アーキテクチャ図

ユーザー行動の把握

この実装に AWS Lambda を選択した理由

Lambda は、データの変更、システム状態の変化、ユーザーによるアクションにリアルタイムに応答する必要があるデータ駆動型のアプリケーションに最適です。こうしたアプリケーションでは、通常、データストアに接続してデータのアクセスと分析を行い、バッチ処理、ストリーム分析、機械学習の推論を実行します。Lambda は、Kinesis Data Streams、Data Firehose、S3、CloudWatch Events、CloudWatch Logs、DynamoDB などのデータストアと統合されており、現在 17 個のイベントソースがサポートされているため、このようなアプリケーションに最適です。   

このモジュールで使用するサーバーレスリソース

AWS Kinesis Firehose 配信ストリーム: Kinesis Firehose は、可用性の高いマネージド型のリアルタイムストリーミングサービスで、データレコードを受け取り、Amazon S3 バケット、Amazon Redshift データウェアハウスクラスターなどの AWS 内の複数のストレージ送信先に自動的にそのレコードを取り込みます。また、Kinesis Firehose では、ストリームで受信したすべてのレコードを AWS Lambda で作成したサーバーレス関数に自動的に送信できます。このため、レコードが指定の送信先に集約され、保存される前に、記述したコードを使用してレコードの処理や変換を行うことができます。

Amazon S3 バケット: 新しいバケットを S3 に作成します。このバケットでは、処理されたすべてのクリックイベントレコードがファイルに集約され、オブジェクトとして保存されます。

AWS Lambda 関数: AWS Lambda を使用すると、開発者はロジックが要求するものを含むコード関数のみを記述できます。そしてコードをデプロイして呼び出し、信頼性を高め、インフラストラクチャをまったく管理することなくスケーリングができます。ここでは、AWS SAM を使用してサーバーレスコード関数を定義します。この関数は、AWS Lambda にデプロイし、Python で記述します。この関数では、配信ストリームによって受信したクリックレコードを処理し、拡充します。記述したコードは非常に簡単であるため、後から処理を行わなくてもウェブサイトのフロントエンドでレコードの拡充を実行できます。関数では、Mysfit のクリックに関する追加の属性を取得し、クリックレコード (ウェブサイトのフロントエンドによって既に取得されたデータ) を充実させます。ただし、このワークショップでのコードは、サーバーレスコード関数を挿入して、レコードが保存される前に必要な追加の処理または変換をリアルタイムで実行できることを示すことのみを目的とします。Lambda 関数を作成し、Kinesis Firehose 配信ストリームをその関数のイベントソースとして設定すると、配信ストリームでは、クリックレコードをイベントとして、作成したコード関数に自動的に配信し、コードによって返される応答を受信し、更新されたレコードを指定された Amazon S3 バケットに配信します。

Amazon API Gateway REST API: AWS Kinesis Firehose では、AWS の他のサービスと同様にサービス API を提供しています。この場合、PutRecord オペレーションを使用して、ユーザークリックのイベントレコードを配信ストリームに入力します。ただし、ウェブサイトのフロントエンドを直接 Kinesis Firehose PutRecord API と統合したくはありません。そのために、フロントエンドコード内で AWS 認証情報を管理して、PutRecord API への API リクエストを承認する必要があります。これにより、利用しているダイレクト AWS API がユーザーに表示されます (悪意のあるサイト訪問者が、形式の正しくないレコードや、実際のユーザーの行動を把握するという目的を妨げるレコードを配信ストリームに追加しようとする可能性があります)。このため、代わりに Amazon API Gateway を使用して Kinesis Firehose の PutRecord API への AWS サービスプロキシを作成します。こうすることで、リクエストに関してフロントエンドで AWS 認証情報を管理する必要がないパブリック RESTful エンドポイントを自分で作成できます。また、API Gateway でリクエストマッピングテンプレートを使用します。これにより、リクエストのペイロード構造を自分で定義し、リクエストを意図した構造に制限し、正しい形式のリクエストを Kinesis Firehose PutRecord API で必要な構造に変換できます。

IAM ロール: Kinesis Firehose には、受信したレコードをイベントとして、作成した Lambda 関数に配信し、処理されたレコードを送信先の S3 バケットに配信できるサービスロールが必要です。Amazon API Gateway API にも、受信した API リクエストごとに Kinesis Firehose 内で PutRecord API を呼び出すことができる新しいロールが必要です。

実装手順

  • A: 新しい CodeCommit リポジトリを作成する

    CloudFormation を使用してデプロイするこの新しいスタックには、インフラストラクチャ環境のリソースだけでなく、ストリーミングイベントを処理するために AWS Lambda によって実行されるアプリケーションコードも格納されます。インフラストラクチャとコードの作成を 1 つのデプロイにまとめるために、AWS Cloud9 IDE に事前にインストールされている AWS のもう 1 つのツール AWS SAM CLI を使用します。AWS Lambda 関数のコードは、関数コードを .zip パッケージで Amazon S3 バケットにアップロードすることでサービスに配信されます。

    SAM CLI ではこのプロセスが自動化されます。SAM CLI を使用して、Lambda 関数のすべてのコードが保存されているファイルシステムでローカルに参照する CloudFormation テンプレートを作成できます。SAM CLI によって .zip ファイルにパッケージ化され、指定した Amazon S3 バケットにアップロードされ、AWS Lambda にデプロイするために .zip パッケージがアップロードされた S3 の場所を示す新しい CloudFormation テンプレートが作成されます。SAM CLI によって生成された CloudFormation テンプレートを AWS にデプロイし、SAM CLI によってアップロードされたコードパッケージを使用する Lambda 関数と共に環境が作成されることを確認できます。

    最初に、ストリーミングサービスのコードが格納される新しい CodeCommit リポジトリを作成します

    aws codecommit create-repository --repository-name MythicalMysfitsStreamingService-Repository

    このコマンドの応答で、"cloneUrlHttp" の値をコピーします。https://git-codecommit.REPLACE_ME_REGION.amazonaws.com/v1/repos/MythicalMysfitsStreamingService-Repository のような形式です。

    次に、空の新しいリポジトリを IDE にクローンします。

    cd ~/environment/
    git clone {insert the copied cloneValueUrl from above}
    B: ストリーミングサービスのコードベースをコピーする

    作業ディレクトリをこの新しいディレクトリに変更します

    cd ~/environment/MythicalMysfitsStreamingService-Repository/

    この新しいリポジトリディレクトリを module-5 アプリケーションコンポーネントにコピーします

    cp -r ~/environment/aws-modern-application-workshop/module-5/app/streaming/* .

    このモジュールの CloudFormation テンプレートをコピーします

    cp ~/environment/aws-modern-application-workshop/module-5/cfn/* .
  • A: pip を使用して Lambda 関数の依存関係をインストールする

    用意されたすべてのアーティファクトを使用して設定されたリポジトリディレクトリができました。

    フルスタックを作成するための CFN テンプレート

    Lambda 関数のコードを含んでいる Python スクリプト: streamProcessor.py

    これは、AWS のお客様が使用する一般的な方法で、CloudFormation テンプレートとアプリケーションコードを 1 つのリポジトリに保存します。こうすることで、1 つの場所で、アプリケーションと環境へのすべての変更を追跡できます。

    ただし、streamProcessor.py ファイル内のコードを見ると、リクエスト Python パッケージを使用して、以前に作成した Mythical Mysfits サービスに対して API リクエストを行っていることがわかります。AWS のお客様によって使用するライブラリもライブラリのバージョンも異なるため、外部ライブラリは AWS Lambda ランタイム環境に自動的に追加されません。

    Lambda サービスにアップロードする前に、ライブラリのすべての依存関係と Lambda コード関数を一緒にパッケージ化する必要があります。Python パッケージマネージャー pip を使用してこれを実行します。Cloud9 ターミナルで以下のコマンドを実行し、関数コードと一緒にリクエストパッケージと依存関係をローカルにインストールします。

    pip install requests -t .

    このコマンドが完了すると、リポジトリディレクトリ内に複数の python パッケージフォルダが追加されます

    B: Lambda 関数コードを更新する

    Lambda 関数コードのデプロイ準備を完了する前に、1 つのコード変更を行う必要があります。streamProcessor.py ファイル内の 1 つの行を、Mysfits サービス API の ApiEndpoint (モジュール 4 で作成し、ウェブサイトのフロントエンドで使用したものと同じサービス ApiEndpoint) と置き換える必要があります。

    replace-api-endpoint

    このサービスでは、DynamoDB の MysfitsTable との統合を処理します。DynamoDB のテーブルと直接統合される Lambda 関数を記述することもできますが、そうすると、初めてマイクロサービスを構築するという目的を達成できず、同じテーブルに複数の個別のコードベースが統合された状態になります。代わりに、既存のサービスを使用してこのテーブルと統合し、疎結合でモジュール式のアプリケーションアーキテクチャを構築します。

    C: コードを CodeCommit にプッシュする

    新しいリポジトリにコードの変更をコミットして、変更を CodeCommit に保存します。

    git add .
    git commit -m "New stream processing service."
    git push
  • A: Lambda 関数コードパッケージの S3 バケットを作成する

    Python ファイルで行を変更し、コードをコミットしたので、AWS SAM CLI を使用してすべての関数コードをパッケージ化し、S3 にアップロードし、ストリーミングスタックを作成するためのデプロイ可能な CloudFormation テンプレートを作成できます。

    最初に、AWS CLI を使用して新しい S3 バケットを作成します。このバケットに、Lambda 関数コードのパッケージがアップロードされます。S3 バケットの名前は、AWS のすべてのお客様の間でグローバルに一意である必要があるため、このバケット名の末尾をお客様に固有の文字列に置き換えます。

    B: SAM CLI を使用して Lambda のコードをパッケージ化する

    バケットが作成されると、SAM CLI を使用してコードをパッケージ化してアップロードし、CloudFormation テンプレートを変換する準備ができました。コマンドの最後のパラメータを前のステップで作成したバケット名に必ず置き換えます (このコマンドでは、ユーザーのターミナルはリポジトリの作業ディレクトリから出ていないことを想定)。

    sam package --template-file ./real-time-streaming.yml --output-template-file ./transformed-streaming.yml --s3-bucket replace-with-your-bucket-name

    このコマンドが正常に実行された場合、./MythicalMysfitsStreamingService-Repository/ ディレクトリ内に transformed-streaming.yml ファイルが新しく作成されます。その内容を見ると、サーバーレス Lambda 関数の CodeUri パラメータが、SAM CLI によってパッケージ化されたコードがアップロードされたオブジェクトの場所で更新されていることがわかります。

    C: AWS CloudFormation を使用してスタックをデプロイする

    SAM CLI コマンドによって、新しいフルスタックを作成するために実行する必要がある CloudFormation コマンドが返されます。ただし、スタックでは IAM リソースを作成するため、コマンドにパラメータを 1 つ追加する必要があります。以下のコマンドを実行して、ストリーミングスタックをデプロイします。

    aws cloudformation deploy --template-file /home/ec2-user/environment/MythicalMysfitsStreamingService-Repository/cfn/transformed-streaming.yml --stack-name MythicalMysfitsStreamingStack --capabilities CAPABILITY_IAM

    このスタックの作成が完了したら、完全なリアルタイム処理マイクロサービスが作成されます。

    コードの変更のみが Lambda 関数に対して行われ、CloudFormation スタックの残りの部分は変更されないという将来のシナリオでは、上記と同じ AWS SAM CLI コマンドと CloudFormation コマンドを繰り返し使用できます。これにより、インフラストラクチャ環境は変更されず、コードが Lambda 関数にデプロイされます。

  • A: ウェブサイトのコンテンツを更新する

    ストリーミングスタックの稼働が開始されたので、Mysfit プロフィールがユーザーによってクリックされるたびにイベントをサービスに送信する JavaScript を含んだ新しいバージョンの Mythical Mysfits フロントエンドをパブリッシュする必要があります。

    新しい index.html ファイルは ~/environment/aws-modern-application-workshop/module-5/web/index.html にあります。

    このファイルには、モジュール 4 と同じプレースホルダーが含まれており、このプレースホルダーは更新する必要があります。また、このファイルには、作成した新しいストリーム処理サービスエンドポイントのプレースホルダーが追加されています。以前の変数の値については、モジュール 4 で更新した前の index.html ファイルを参照してください。

    新しいストリーミングスタックに対して以下のコマンドを実行し、ストリーム処理サービスの新しい API Gateway エンドポイントを取得します。

    aws cloudformation describe-stacks --stack-name MythicalMysfitsStreamingStack
    B: 新しいサイトのバージョンを S3 にプッシュする

    streamingApiEndpoint の index.html 内の最後の値を置き換えるとMythical Mysfits ホームページの最後の更新をパブリッシュする準備が整います。

    aws s3 cp ~/environment/aws-modern-application-workshop/module-5/web/index.html s3://YOUR-S3-BUCKET/

    ブラウザでもう一度 Mythical Mysfits ウェブサイトを更新すると、ユーザーが Mysfit プロフィールをクリックするたびに記録し、パブリッシュするサイトが完成します。

    処理されたレコードを表示するために、レコードは、MythicalMysfitsStreamingStack の一部として作成された送信先 S3 バケットに送信されます。

    これで最新のアプリケーションアーキテクチャが完成しました。AWS コンソールと Mythical Mysfits を立ち上げるために作成したすべてのさまざまなサービスを詳しく確認することをお勧めします。

  • リソースに対する課金がこれ以上行われないようにするために、ワークショップ中に作成したすべてのリソースを必ず削除してください。AWS コンソールを使用して、作成したリソースを詳しく確認し準備ができたときにリソースを削除することをお勧めします。

    AWS CloudFormation を使用してリソースをプロビジョニングした 2 つのケースについては、スタックごとに以下の CLI コマンドを実行してリソースを削除できます。

    aws cloudformation delete-stack --stack-name STACK-NAME-HERE

    以下の AWS コンソールにアクセスして、作成したすべてのリソースを削除できます。この各コンソールには、Mythical Mysfits ワークショップで作成したリソースが含まれています。

まとめ

このワークショップの目的は、AWS を土台とした最新のアプリケーションアーキテクチャを設計し、構築する開発者がどのようなものであるのかを経験していただくことでした。AWS を利用する開発者は、AWS CLI を使用してリソースをプログラムによってプロビジョニングし、AWS CloudFormation を使用してインフラストラクチャの定義を再利用できます。また、コードサービスで構成される AWS の開発者用ツールを使用してコードの変更を自動的にビルドおよびデプロイし、開発者が自分でサーバーをプロビジョニングしたり、管理したりしなくても、さまざまなコンピューティングとアプリケーションのサービスの機能を利用できます。

次のステップとして、作成した Mythical Mysfits ウェブサイトの内部の動作を理解するために、提供された CloudFormation テンプレートとそのテンプレートで宣言されているリソースを詳しく確認してください。

AWS の最新のアプリケーションワークショップを楽しんでいただけたでしょうか。 このチュートリアルは GitHub でホストされているため、提案がある場合は Issue を送信することができます。また、コードの改善に協力する場合は、GitHub プルリクエストを初期化できます。

AWS 開発者センターでは、AWS での開発について詳しく学習することができます。

おめでとうございます。

AWS でモダンウェブアプリケーションを構築できました。
友人と共有したり、私たちに意見や感想を送ってみたりしてみましょう。

Twilight Glitter はあなたの作業に感動しています