助け合いフォーラム
要件に合う最も適切なWeb3層構成はどれか。
正解
Amazon API Gateway、AWS Lambda、Amazon DynamoDB
解説
Lambda関数の実行時間は1回につき最長15分で、実行時間と選択したメモリの容量に対する従量課金制です。
Amazon API GatewayはAWSサービスと連携するAPIの作成や管理ができる機能です。API GatewayではREST APIとWebsocket APIの2種類のAPIを作成できます。
API Gatewayはマネージドサービスなので、Lambdaと組み合わせることで完全にサーバーレスでWebアプリケーションを実行できます。
Amazon DynamoDBはKey-Value型のデータ形式をサポートするNoSQLのデータベースです。Key-Value型とはキーに対して値がセットになっている形式のデータのことで、RDB(関係データベース)のようにある表AとBのデータを結合して結果を得たり分析するような利用方法よりも、単一のデータを格納・取得するというシンプルな利用に向いています。
DynamoDBに保存するデータは3つのAZに自動的に保存されるので、耐障害性にも優れています。
設問の要件と照らし合わせると以下のようになります。
- AWS Lambdaは、リクエストが不定期に発生するプログラムの実行に適しています。
- Amazon API Gatewayは、REST APIを作成可能でLambdaと組み合わせてWebアプリケーションを実行できます。
- DynamoDBは、Key-Value型のデータベースで3つのAZに自動的に保存されます。
どのサービスもマネージドサービスなので、突然大量のリクエストが発生しても自動スケーリングで対応できます。
したがって正解は
・Amazon API Gateway、AWS Lambda、Amazon DynamoDB
です。
下記の図は、API Gateway経由でLambda関数を実行してDynamoDBテーブルを検索するイメージです。

その他の選択肢については、以下のとおりです。
・Amazon API Gateway、Amazon Fargate、Amazon DynamoDB
AWS Fargateはコンテナ向けのサーバーレスコンピューティングエンジンです。Fargateを利用するにはWebアプリケーションをコンテナ化する必要があります。
プログラムをアップロードすれば即座に実行できるLambdaの方が簡潔に要件を満たせるので、誤りです。
・Amazon CloudFront、Amazon Fargate、Amazon DynamoDB
Amazon CloudFrontはAWS上で動作する安全で高速なコンテンツ配信ネットワークです。CloudFrontのバックエンドにREST APIを使用したAPI Gatewayを配置することはできますが、 CloudFront自体にREST APIを作成することはできないので誤りです。
また、前述の通りFargateは設問の要件に適していません。
・Amazon CloudFront、Amazon Lambda、Amazon Redshift
Amazon Redshiftはペタバイト級のストレージに対応したデータウェアハウスです。Key-Value型のデータ形式ではないので、誤りです。
また、前述の通りCloudFrontは設問の要件に適していません。
参考
AWS Lambda(ラムダ)はサーバーレスでプログラムのコードを実行できるフルマネージドサービスです。サーバーレスとは、EC2インスタンスなどのサーバーを必要とせずリクエスト発生時にだけプログラムが実行されるアーキテクチャのことです。サーバーレスアーキテクチャでは、インフラストラクチャの管理は完全にAWSによって行われます。
Lambdaを利用すると次のようなメリットがあります。
・プログラム実行環境の構築や運用が不要になる
・プログラムはリージョン内の複数のAZに分散して配置される(耐障害性・可用性の向上)
・プログラムへのリクエスト数に応じたスケーリングが自動的に行われる(拡張性の向上)
開発したプログラムを動作させるためには、通常、実行環境となるサーバーが必要です。サーバー管理は構築・運用ともに負担の大きな作業ですが、Lambdaを利用することにより煩雑な業務を行わなくて済むようになりプログラムの開発に集中できます。
【Lambda関数】
Lambdaで実行されるコードを「Lambda関数」といいます。
Lambda関数は以下のような特徴があります。
・開発言語:Java、Node.js、Pythonなど様々な開発言語に対応
・実行時間:最長15分
・課金方式:リクエスト数に基づく課金と実行時間(単価はメモリ量に依存)に基づく課金の合計
・実行タイミング:特定のイベントがトリガーとして発生したときに実行
ユーザーは、Lambda関数を実行するため
・Lambda関数のコード作成と更新、環境変数設定、IAMロール設定など、アプリケーションに関する設定
・Lambda関数を実行するメモリサイズや最大実行時間の指定など、リソースに関する設定
などを行います。
実行時間が15分以上になる処理や常時稼働が必要なアプリケーションには適していないので、EC2インスタンスやコンテナなどで運用する検討が必要です。
Lambdaを1年以上継続して利用する場合は「Compute Savings Plans」で契約すると、サービスを割引価格で利用できます。Compute Savings Plansは1年または3年の期間、一定のサービス使用量(1時間あたりの利用料金)を決めて契約することで、通常よりも低価格になる購入オプションです。
【Lambda関数のトリガー】
Lambda関数実行の起点となるイベントを「トリガー」といいます。以下はトリガーとして設定できるイベントの一例です。
・Amazon S3バケットにオブジェクトが作成された時
・Amazon DynamoDBのテーブルに変更があった時
・Amazon SQSのキューにメッセージが追加された時
・Amazon SNSからトピックが通知された時
・Amazon API Gateway経由で直接Lambda関数が呼び出された時
例えば、ユーザーからアップロードされた画像ファイルがS3バケットに保存(オブジェクトが作成)された時に、Lambda関数が実行されて画像ファイルの情報をDynamoDBに書き込むといった利用方法があります。

【Lambda関数のアクセス権限】
Lambda関数には実行ログを出力するために、CloudWatch Logsへのアクセス権限が割り当てられています。デフォルトではCloudWatch Logs以外へのアクセス権限はないので、Lambda関数から他のAWSサービスへアクセスさせたい場合はアクセス権限の設定が必要です。Lambda関数のアクセス権限は、他のAWSサービスへのアクセス権限を持つIAMロールによって付与します。その際、Well-Architected Frameworkの「最小権限の原則」に基づき、コード実行に必要な最低限の権限のみ割り当てることが推奨されています。
[Lambda関数にDynamoDBへのアクセス権限を割り当てる時のイメージ]

【Lambda関数のVPCアクセス】
作成したLambda関数はLambda専用のセキュアなVPCに配置されます。このLambda専用のVPCからは、インターネットや、インターネットを経由してパブリックサブネット内のAWSリソースにはアクセスできますが、プライベートサブネット内のAWSリソースへはアクセスできません。

Lambda関数からプライベートサブネット内のAWSリソースへアクセスさせたい場合は「VPCアクセス」の設定をします。VPCアクセスではアクセスしたいAWSリソースのあるVPCやサブネットの選択と、Lambda関数のセキュリティグループを設定します。VPCアクセスを設定するとLambda関数がサブネット毎に接続用のENI(Elastic Network Interface)を作成して、プライベートサブネット内のAWSリソースへアクセスします。
VPCアクセスを設定したLambda関数は、ENIを作成したサブネットへアクセスできるようになる代わりに、インターネットへアクセスできなくなります。

VPCアクセスを設定したLambda関数からインターネットへアクセスしたい場合は、プライベートサブネットからインターネットへアクセスする方法と同様に、NATゲートウェイまたはNATインスタンスを経由します。また、インターネットを経由せずにパブリックなAWSリソースへアクセスしたい場合は、VPCエンドポイントを経由します。

【Lambda関数の同時実行】
Lambda関数は、発生したイベントの数だけ同時実行されます。ある特定の時点で、実行中のLambda関数の個数を「同時実行数」といいます。同時実行数には上限値が設定されており、東京リージョンでのデフォルトの上限値は1000です。
この上限値はアカウント全体のすべてのLambda関数に対して適応されます。そのため、ある特定のLambda関数で多数の同時実行が進行している場合、別のLambda関数の実行が制限される可能性があります。このような状況を避けるため、事前に特定のLambda関数に対して「同時実行」の数を予約できます。たとえば200を予約しておくと、その関数は200まで同時実行ができ、他の関数は合計して800までの同時実行が可能となります。
Lambda関数が初めて実行される場合や一定期間実行されていない場合は、Lambda関数の実行環境であるランタイム環境の準備に時間がかかるため、Lambda関数の処理が開始されるまで時間がかかります。(コールドスタート)
一方、同じLambda関数に対するリクエストが継続的に発生する場合は、ランタイム環境が再利用されるため準備処理が省略され、Lambda関数の開始までの時間が短くなります。(ウォームスタート)
Lambda関数のランタイム環境を事前に準備しておくことを「プロビジョニング」といい、「プロビジョニングされた同時実行」を予約することで、Lambda関数の起動時間を短縮し、レスポンス時間を改善できます。これは、Lambda関数の処理でレイテンシーの低減が重要な場合に特に有効です。(ただし「プロビジョニングされた同時実行」を予約する場合、別途料金がかかります)
【暗号化ヘルパー】
Lambda関数の環境変数には、APIキー、データベースの認証情報、アクセスキーなどの機密情報が含まれることがあります。これらの情報を暗号化することは、機密情報のセキュリティを強化し、コンプライアンスを遵守し、意図しない情報の流出を防ぐために非常に重要です。
Lambda関数の設定画面だけでなく、ログやエラーメッセージでも平文で表示されないようにする必要があります。
暗号化ヘルパーは、Lambda関数で使用する環境変数をAWS KMSを使用して暗号化し、実行時に復号して利用するためのツールです。
AWS Key Management Service(KMS)は、暗号化に使用する鍵(キー)を作成・管理するサービスです。暗号化ヘルパーはKMSを利用してデータを暗号化し、安全に管理することができます。

【Amazon API Gateway】
Amazon API GatewayはAWSサービスと連携するAPIの作成や管理ができる機能です。API(Application Programming Interface)とは、クライアントからのリクエストをアプリケーションサーバーに送り、アプリケーションサーバーからのレスポンスをクライアントへ返す接続口(インターフェイス)のことです。
下記はAPI Gatewayで作成したHTTP APIの実行例です。クライアントからHTTP(HTTPS)などでAPIを呼び出して、テキストやJSONなどの形式で得たい情報を取得します。

API Gatewayはマネージドサービスなので、Lambdaと組み合わせることで完全にサーバーレスでWebアプリケーションを実行できます。
例えばクライアントからのHTTPリクエストをAPI Gatewayで受信し、それをトリガーとしてLambda関数を実行させ、レスポンスをAPI Gateway経由で返すことができます。
API Gatewayで作成できるAPIは、クライアントとサーバー間の接続方法や機能によって以下の3種類があります。
■REST API(RESTful API)
クライアントからのリクエストに対してレスポンスを返す形式のAPIです。サーバーが扱う情報はURI(URL)で定義されており、クライアントはHTTP(HTTPS)でリクエストを送信することでレスポンスを得ます。
データベースの検索など、クライアントからのリクエストに応答するアプリケーションで使われます。
なお、REST API(RESTful API)とはREST(REpresentational State Transfer)という原則にのっとったAPIのことです。通信の状態が管理されない「ステートレス」な接続方式です。
[REST APIの処理イメージ]

■HTTP API
REST APIよりも低遅延かつコスト効率を高くする目的で設計されたAPIです。REST APIと同じ形式のAPIですが、APIキャッシュ(後述)を利用できないなど細かな差異があります。
■WebSocket API
クライアントとサーバー間でリアルタイムな情報のやり取りを目的とするAPIです。REST APIとは違い、継続的なデータの送受信を行えます。
チャットや株価情報のような常に情報をモニタリングするようなアプリケーションで使われます。
なお、WebSocket APIとはサーバー・クライアント間で双方向のセッションを確立できる技術を利用したAPIのことです。通信の状態を管理される「ステートフル」な接続方式です。
[WebSocket APIの処理イメージ]

【API キャッシュ】
Amazon API Gatewayにはクライアントへ送信したデータを保存する「API キャッシュ」機能があります。REST APIではどのクライアントからでも同一のリクエストであれば同一のレスポンスになります。API キャッシュではクライアントに送ったレスポンスをAPI Gatewayでキャッシュし、再度同一のリクエストを受け取るとキャッシュからデータを返します。API キャッシュから応答を返すことにより、Lambda関数の実行を省略できるのでレスポンス速度が向上します。
【API GatewayのVPCリンク】
Amazon API Gatewayで作成したAPIはユーザーが管理するVPC外に配置されます。そのため、作成したAPIからインターネットを経由してパブリックサブネット内のAWSリソースにはアクセスできますが、プライベートサブネット内のAWSリソースへ直接アクセスすることはできません。

API Gatewayからプライベートサブネット内のAWSリソースへアクセスさせたい場合は「VPCリンク」を作成します。これにより、APIとプライベートサブネット内のリソースとの間でインターネットを経由しないセキュアな通信が可能になります。
VPCリンク作成時に、アクセスしたいAWSリソース(下図の例ではEC2インスタンス)を直接指定することはできません。Network Load Balancerを対象として指定します。※対象として指定できるリソースはAPIの種類により異なります。

【API Gatewayのオーソライザー】
API Gatewayのオーソライザーを使用すると、APIへのアクセス制御を実装することができます。オーソライザーには、Amazon Cognito(*)のユーザープールを使用する方法と、Lambda関数を使用する方法があります。
※ Amazon Cognito: モバイルアプリケーションやWebアプリケーション向けのユーザー認証機能を提供するサービス
Cognitoのユーザープールを使用する方法は、Cognitoが提供するマネージド型の認証機能を使用するため、開発者は認証プロセスについて自身で管理する必要がありません。
Lambda関数を使用する方法は、開発者自身が認証プロセスを作成する必要があります。独自のロジックでAPIへのアクセス制御を実装できるため柔軟性は高くなりますが、セキュリティ対策など管理の複雑さが増加します。

[Cognitoユーザープールを使用したオーソライザーでのアクセス制御のイメージ]

[Lambda関数を使用したオーソライザーでのアクセス制御のイメージ]

【独自ドメイン名の使用】
API Gatewayで作成したAPIへアクセスするためのURLに、独自ドメイン名を設定することができます。独自ドメイン名を使用する場合、API Gateway側で独自ドメイン名の作成時に、AWS Certificate Manager(ACM)で管理されるSSL/TLS証明書を選択します。この時に使用する証明書は、APIのエンドポイントタイプによって異なる場合があります。リージョン別のエンドポイントを使用している場合には、同じリージョンのACMで発行またはインポートされた証明書を使用します。エッジ最適化(CloudFrontを組み合わせて使用する)エンドポイントを使用している場合には、us-east-1リージョンのACMで発行またはインポートされた証明書を使用します。
また、APIへアクセスするためのURLにワイルドカードを含んだ独自ドメイン名を使用することもできます。これにより、1つの独自ドメイン名を作成するだけで、「aaa.example.com」や「bbb.example.com」のようにサブドメインの異なる複数の独自ドメイン名をサポートすることが可能になります。この場合、指定する証明書も、ドメイン名にアスタリスクを含むワイルドカード証明書である必要があります。また、DNSサーバ側のDNSレコードも、ワイルドカードを用いた独自ドメイン名を登録します。
[独自ドメイン名の設定画面]

【Canaryリリース】
API Gatewayでは、「ステージ」という概念を使用して、APIの異なるバージョンや開発段階を管理します。これにより、開発、テスト、本番などの異なる環境でAPIを個別に管理できます。
Canaryリリースは、新しいバージョンのAPIを段階的にリリースする方法です。まず、既存の本番ステージに新しいAPIバージョンをデプロイし、一部のトラフィックを新しいバージョンに向けます。例えば、初めは20%のトラフィックを新バージョンに割り当てます。新バージョンが安定して動作することが確認されたら、トラフィックの割合を徐々に増やしていき、最終的には全トラフィックを新バージョンに移行します。もし問題が発生した場合は、すぐに元のバージョンに戻すことができます。Canaryリリースを利用することで、リスクを分散し、ユーザーへの影響を最小限に抑えることができます。
[API GatewayでのCanaryリリースのイメージ図]

Lambdaか、Fargateか
・問題の要件では「コスト最適化」や「効率の良い実装」「効率の良い運用」などは求められていない。
(要件としては、「プログラムはJava」、「、REST APIを使用」、「Key-Value型のデータ形式」、「少なくても2ヵ所のAZに自動的に保存」、「リクエストは不定期だが、突然大量のリクエストが発生にも対応」)
・一方で、リクエストの処理時間は記載されておらずLambdaの処理時間(15分)で処理しきれるかは不明
上記のことから、LambdaではなくFargateの方が適切かと考えたのですがこの考えの誤っているところはどこでしょうか。
どなたかコメントいただけると助かります。
・問題の要件では「コスト最適化」や「効率の良い実装」「効率の良い運用」などは求められていない。
要件として明記されていないとしても、AWSが出題する試験である以上、AWS Well-Architectedフレームワークに準拠したソリューションが求められているはずです。
・一方で、リクエストの処理時間は記載されておらずLambdaの処理時間(15分)で処理しきれるかは不明
上記のことから、LambdaではなくFargateの方が適切かと考えたのですがこの考えの誤っているところはどこでしょうか。
誤答解説にもある通りFargateだとコンテナ化する手間が発生します。
処理時間の記載はありませんが、リクエストが大量に発生する可能性があるWebアプリケーションの処理時間が15分を超えるとはあまり考えられにくいです。
メタ的なことを言ってしまえば、処理時間が15分以上だからLambdaが誤りである問題の場合は要件に処理時間が15分以上と書いてありますし、Fargateが正解である問題の場合は大抵要件にコンテナと書いてあります。
ありとあらゆる想定をすることは実務ではリスク管理の点で有効ですが、処理時間が書いてないからLambdaが誤りという免許の学科試験のような引っ掛け問題の可能性を考えていると試験時間が足りなくなる恐れがあります…
コメント
(この回答は参考程度にしてください)
試験問題的には
リクエストは不定期に発生し
をポイントとしていて、(不定期の頻度は不明だが)Fargateでコンテナ化した場合は使われなくても起動しておかなくてはならないし
また、ECSで大量アクセスも想定されるとなるとロードバランサも検討しないといけません。
この点でLambdaが推されてると思います。
試験の話はここまで。
ただ、現実のプロジェクトでは「WebアプリケーションのプログラムはJavaで開発されており」がかなりネックになります。
(「Webアプリケーションシステムを設計している」なのだから、「Javaで開発予定で」の間違いなんですかね)
もしすでに開発が済んでいるアプリケーションならば、Lambdaに対応するコストがいちばん気になる点。
Lambda Web Adapter もありますがなんにせよコンテナ化とコンテナ運用のコストと比較することになると思います。
次にLambdaのメリットは常時起動不要な点にもありますが、Javaは起動が遅いのでアクセスが不定期だとしばしばコールドスタートに陥って応答時間に問題が生まれる可能性もあります。(改良されつづけてはいるものの、今でも無視はできないと思う)
プロビジョニングされた同時実行は要は常時起動なので、コンテナの常時起動を避けたのに本末転倒になる可能性も。
SnapStartはそれ用の修正というか、必要なライブラリだけロードさせておくメソッドの作成が必要になるはず。
15分については他の方も似た様なことをおしゃってますが、ユーザーを15分も待たせるのはWebアプリケーションとして問題がありそうですし、
裏で15分回したいならそこはもうリクエスト受け付けたら別のECSやEC2のバッチサーバー(バッチアプリケーション)に投げてユーザーは待たせない様にすべきです。
というかAPI Gatewayのタイムアウトにひっかかる気もします。
「WebアプリケーションのプログラムはPythonで開発予定で」だったらLambdaから検討するんですけど、
Javaで開発しててLambda使いたいとなると軽量化のためにawsSDK削ったりフレームワーク使うのやめるの検討とかいろいろ気にしなくてはいけないことが多かったというお話でした。
コメント
この投稿に対して返信しませんか?
k kiritomo2
2025/02/26 18:00
ありがとうございます。 問題に明記されていない場合は、以下前提としておく必要があると理解しました。 ・どのような問題でも常にコスト最適化、運用効率の最適化は求められている ・処理時間が15分以上と書かれていなければ15分以内に終わる処理である