よくあるAWSのサーバーレスアーキテクチャ考察

クラウドアーキテクチャ クラウドコンピューティング こんにちは、ソニー・ミュージックエンタテインメント しんろくです。

この記事は、実務でWebアプリケーションを設計および実装しているプログラマ向けの内容です。 また、

  • AWS認定 ソリューションズ アーキテクト アソシエイト/プロフェッショナル
  • AWS認定 デベロッパー アソシエイト

を取得、またはそれを目指して勉強中の方々に読んでいただければ幸いです。

本記事の背景

AWSの学習を進めていくと API Gateway (以下、APIGW) + Lambda + DynamoDB (以下、DDB) のような サーバーレスアーキテクチャを学習する機会があるかと思います。 最近いろいろなプロジェクトのサーバーレスアーキテクチャを見る機会があったので、 ゆるく考察してみようかと思いました。

前提知識と免責事項

  • JavaScriptで実装されるシングルページなWebブラウザアプリケーションを考える
  • 認証認可はCognitoを使う
  • 各種サービスの使い方などは各自お調べいただく

今回考察するアーキテクチャのパターン

今回考察するアーキテクチャのパターン

Pattern 1: JSからAPIGWを経由し、Lambdaを起動、DDBにアクセス

最近強く思うのが、Cognitoで認証認可しているのになんでAPIGW使ってるんだろう?という疑問。 APIGWを守る方法のひとつに、Cognito ユーザープールをオーソライザーとして使用する方法があるけれども Cognitoで認証が通っているならIAMロールでリソース制御できるわけだからAPIGWいらないのでは? と思います。

Cognito認証後にAPIGWを使う便利なアーキテクチャとしては 別のCognito認証したサービスからこちらのAPIGWにアクセスしたいとき 別のCognitoユーザープールを指定して許可してあげられるので、そういう使い方は便利と思います。

単一アプリケーションでAPIGW→Lambda→DDBって経由させるのは APIGW用にカスタムドメインを考えたり(オプション) ソフトリミットを考えたり 障害発生したときに追うのがめんどうだったりするので極力やりたくない。

Pattern 2: JSからlambda:InvokeFunctionする

その昔ぼくにも、「ブラウザから直接Lambdaキックするの、なんか気持ち悪い」と思っていた時期がありました。今は躊躇なくキックしています。

これはCognitoで認可されているので当然アクセス制御は問題ありません。 セッションハイジャックされない限りAWSが保証してくれるはず。

APIGWを経由しない分、アクセス負荷はどうなるかというと Lambdaは並列起動なので大して問題にならないでしょう。

仮にスロットリングが発生するようなアクセスは APIGWが前段にいようがいまいがLambdaの設定の問題なので そのときは起動数の制限緩和などを考えるだけです。

Pattern 3: JSからDDBにアクセスするパターン

もしLambdaをNodejs以外で実行したい場合は 必然的に先のパターン2しか取れないのですが LambdaをNodejsで動かしている場合は、このパターンを選択する余地があります。

Lambdaの場合と同様、DDBへのリソースアクセス制御はIAMロールで守られるので AWSが守ってくれるはずです。

Lambda を経由する場合との相違点は ビジネスロジックを、Lambdaに持たせるか、ブラウザアプリに持たせるか というところかなと思います。

ロジックをブラウザに持たせることの主なメリット・デメリットは下記のとおり。

メリット デメリット
Lambda 経由しないので安い デプロイサイズ肥大化
HTTPリクエスト削減による高速化 ロギングを自前で実装(CloudWatchなどを使いたいときにやや面倒)

ブラウザアプリからDDBを直接参照できるということは DDBがlocalStorageのようにカジュアルに使えるようになるということだったりします。 昨今、WebAssemblyにてSQLite3PostgreSQLなんかもブラウザアプリ上で動かせるようになってきていますしね。

Lambda を経由しないのでLambdaの起動時間やHTTPリクエスト処理時間が短縮されることは自明です。 一方でロジック実装にともなうデプロイサイズが(Webpackなどのバンドラを使ったとしても)大きくなるので、アプリケーション起動に時間がかかるというSPAの欠点が目立ちやすくなります。(ここはフレームワークが頑張ってLazy Loadingしてくれるといいですね。。。)

もうひとつ、デプロイサイズが大きくなるということは、通信量に跳ね返ってくるわけですが これはLambdaでロジックを実装した場合のコードサイズ(S3保存1)費用とCloudFrontアウトバウンド費用との比較になります。 まぁでもJavaScriptアプリケーションのサイズなんてたかが知れているので、大した金額にはならないと思います。

結局APIGWは不要なのか?

これを読んで「APIGWいらないのか…」って思った方がいらっしゃったらすみません。 今の世は世知辛い時代なのでCognito認証したあとでも悪意のあるユーザーがいると思ってAPIGWを前段においてAWS WAFでシステムを守ることも大切かもですね。

まとめ:みなさんはどのように設計していますか?

よくあるAWSサーバーレスアーキテクチャをゆるく考察をしてみました。 「サーバーレスそれすなわち APIGW + Lamdba + DDB !」 というSAMな考えに囚われていると他の可能性を見失いがちになるので いろいろな設計を模索していきたいと思います。