[レポート] SaaS microservices deep dive: Simplifying multi-tenant development #reinvent #SAS405

2022.12.26

いわさです。

YouTube で公開されている AWS re:Invent 2022 Breakout Session の SaaS microservices deep dive: Simplifying multi-tenant development (SAS405) のセッションレポートです。

このレポートでは数分でササッと読めるくらいでセッションのポイントと見どころを紹介したいと思います。
興味を持って頂けた方は以下のアーカイブ動画を是非ご視聴ください。

セッション概要

SaaS環境を構築する段階で、マルチテナントがチームのビルダーがマルチテナントマイクロサービスを設計およびコーディングする方法にどのように影響するかに注目が移ります。
マルチテナンシーでは、承認、データアクセス、テナント分離、メトリクス、請求、ロギング、その他多くの考慮事項に対処するための新しいメカニズムを導入する必要があります。
このセッションでは、マルチテナントマイクロサービスを深く掘り下げ、SaaS ビルダーに複雑さを課すことなくマルチテナントマイクロサービスを実現するために使用できるさまざまなパターンと戦略を見ていきます。

スピーカー

  • Michael Beardsley, Principal Solution Architect, AWS

レベル

  • 400 - Expert

セッション内容

マイクロサービスと SaaS のマルチテナンシーの複雑さ

このセッションではマイクロサービスアーキテクチャーを設計する際に、SaaS のマルチテナント要素が追加される際の複雑性とそれに対するアプローチが紹介されているセッションとなっています。

初めに、SaaS を前提としないマイクロサービスがどういったものか簡単に解説されています。

一方で SaaS を設計する場合には以下の要素が重要です。
このあたりは SaaS on AWS で何度も出てきますね。

  • 階層化(ここでは SaaS on AWS のプラン的な階層を指している)
  • ロギング
  • メトリクス
  • ビリング・メータリング
  • 認証
  • 分離性

そして、マイクロサービスで様々なレイヤーでこれらの要素が影響することが説明されています。

カプセル化と再利用

そこで、マイクロサービス開発時に生産性を向上させるために、以降ではカプセル化や再利用を行うアプローチについて解説されます。
データとロジックをある単位でまとめたり、ライブラリを共有したり、複雑さを隠蔽したりなどいくつかのアプローチが Python のコード例を混じえながら解説されていきます。

コードを使って複雑さを説明

まず最初にマルチテナント SaaS にロギング処理を実装するケースを例に複雑性が説明されています。
ログにテナントコンテキストを挿入する必要があるので、以下のようにロギング処理でテナントコンテキストを設定します。

また、その前段階としてテナントコンテキストをどこからか入手する必要があります。
このセッションでは SaaS on AWS のベストプラクティスとされている、認証フローで取得された JWT のカスタムクレームにテナントコンテキストが設定されている前提で、ペイロードからテナントコンテキストを抽出して利用する前提になっています。

このテナント取得処理をコードで実装すると以下のようになります。
先程のロギング処理もそうですが毎回この処理を実装するのは非常に複雑になってしまいます。

ヘルパークラスで再利用

そこでいくつかのヘルパークラスを用意するアプローチが推奨されています。
以下はテナントヘルパーを用意しリクエストからテナント情報を抽出しています。

あるいは以下の場合はロギングヘルパーにリクエスト情報をそのまま渡して JWT からテナントコンテキストを抽出する部分もヘルパークラスに任せてしまうアプローチです。

テナント分離の話

先程の SaaS の複雑さのひとつである分離性についてのアプローチ例がここでは説明されています。
これも SaaS on AWS でよく登場する DynamoDB へアクセスする際のユースケースでどのように分離性を実装するのかを例に解説されています。

ここではポリシーベースで各サービスの権限を制御するパターンを前提に、IdP に Cognito を採用した場合に ID プールでロールマッピングさせる方法と、STS と直接対話してセッションポリシーを付与させる方法の2つが具体的なコード例と共に紹介されています。

DevOps の世界への影響

ここまではコードの実装面の話が中心でしたが、インフラ側の話も少し登場します。
DevOps というよりほぼ CI/CD の話ですが、マルチテナント SaaS でよくあがるテナントオンボーディングについても触れられています。

このセッションではこのあたりの具体的なアプローチについては触れられていませんでした。
CI/CD パイプラインを検討する場合にもマルチテナント SaaS の複雑性が影響してくるのでその点について言及されています。

その文脈でテナントオンボード処理が CI/CD パイプラインに影響していないか、あるいはテナントの Tier が変更された際にも影響しないかなどが挙げられています。

コンピューティングリソースの種類によるアプローチの違い

コードやライブラリを実装していく上でコンピューティングリソースの種類によってもアプローチが違ってくるよという話が解説されています。
このセッションでは EC2、コンテナ(特定リソースの言及なし)、Lambda の 3 種類が挙げられています。

1) 共有ライブラリ

先程ヘルパークラスなどが話に挙がっていましたが、どのように再利用させますかという話をしています。 EC2 と コンテナの場合はライブラリを作成し配置する方法で良く、ただ Lambda だとあちこちでパッケージングしなくてはいけなくなるので Lambda レイヤーを使いましょうねという話でした。

2) バックグラウンドプロセス

2 つ目はバックグラウンドプロセスが必要な場合です。
わかりやすい例として CloudWatch エージェントが挙げられていました。

EC2 ではエージェントやデーモンプロセスで良いのですが、コンテナではサイドカーなどのアプローチを取りましょうとのことでした。

3) インターセプター

ここではリソースタイプごとの方法を紹介し、うまく活用することでコードの複雑さを軽減しようという話がされています。

EC2 とコンテナの場合は Squid や Envoy Proxy のようものを使い、ネットワークプロキシでマイクロサービスの呼び出し前後に割り込む、あるいは .NET の メッセージハンドラなどのミドルウェア機構を使う方法にも触れられていました。

一方で、Lambda の場合は Lambda Extensions が使えますよとのことです。

まとめ

  • マルチテナンスはマイクロサービスアーキテクチャのすべての部分に影響します
  • カプセル化と再利用によりマルチテナント開発を簡素化
  • テナント対応ポリシーによるセキュリティの向上
  • コンピューティングテクノロジーが異なれば、再利用するには異なるアプローチが必要です
  • プロキシとミドルウェアを活用してコードの複雑さを軽減

さいごに

SaaS on AWS の公式ブログなどを見ているとヘルパークラスでテナントコンテキストを、などの話はよく出てきます。
ただ、コンピューティングリソースの種類によってどのように配布しますかなどのアプローチ部分について言及されているものは私は初めて見ました。
セッション動画ではかなりコードの中身の部分に触れられていますので Python のコードが読めたほうが理解しやすいと思います。