ちょっと話題の記事

AWS CDK+Serverlessのアーキテクチャパターンの実装が勢揃い!CDK Patternsの紹介

CDK Patternsの紹介。各設計と実装について少しだけコメントもいれています。
2020.10.05

はじめに

CX事業本部の佐藤智樹です。

今回はAWS CDKでServerlessアーキテクチャを構築する上で参考となる実装が紹介されているCDK Patternsという取り組みが気になったので紹介します。

実装はGitHub上で公開されているので、いつでもすぐにcloneして動かすことができます。

この記事を読むことでAWS CDK+Serverlessで何か開発する際の設計パターンが分かり、独自に検討するより早く実装できるようになります。

正直自分でもこのパターンいいじゃん!使いたい!となったので、CDKで何か作ってる方には絶対参考になると思います。

CDK Patternsとは

以下はCDK PatternsのGitHubリポジトリからの引用です。

CDK Patterns houses an opensource collection of AWS Serverless architecture patterns built with CDK for developers to use. The patterns are sourced via AWS Heroes / Advocates and come with links to their original content

引用元

AWS HeroesやAdvocatesによって紹介されたパターンの引用と実装パターンが併記されています。

パターンの紹介はGitHubだけでなく専用のサイトも構築されており、そちらから各AWSサービスに関連するパターンから調べることもできます。

執筆時点(2020/10/05時点)ではGitHub上で以下のパターンが確認できます。

Polly パターン

Amazon PollyとLambdaやAPI Gatewayと統合するパターンです。API Gateway経由でテキストを受信して音声情報をリクエスト元に返却します。

Pollyパターン

Amazon Translateとも統合しているので、別の言語に翻訳して音声を返却することもできます。Amazon PollyやAmazon Translateの構成をCDKで管理したい場合やAPI経由で簡単に上記のサービスを使ってみたい場合に参考になるパターンです。

s3-angular/react-website パターン

AngularかReactを使ってAmazon S3にサイトをデプロイするパターンです。

AWS s3-react-website パターン

AWS s3-angular-website パターン

cdk-spa-deployコマンドを使用してWebサイトをS3にホスティングすることができます。

※注意:Route53やCloudFrontの設定は行われないためその部分は追加で実施する必要があります。

Basic MQ パターン

AmazonMQを使用して静的カスタムドメインエンドポイントをデプロイするためのパターンです。

Basic MQ パターン

クライアントとブローカー間における、安全でスケーラブルなエンドツーエンドのSSL暗号化メッセージング通信が行えます。(Serverlessなのか?)

The Big Fan パターン

API Gatewayに来たリクエストをAmazon SNSで出力先を分けてからSQSに格納してLambdaで処理するパターンです。

The Big Fan パターン

Statusごとに処理することで全ての処理がSQSで詰まってしまうことを防止したり、別のサービスに処理を投げたりと拡張性が増します。詳しいことは以下の記事のメリット部分などで言及されています。

CloudWatch Dashboard

CloudWatch DashboardをCDKで作成するためのサンプルが紹介されています。

CloudWatch Dashboard

具体的には、API Gatewayが4XX、5XXを返した場合やDynamoDBのキャパシティユニット枯渇によるスロットリングが発生している場合の閾値、アラーム設定、ダッシュボード作成が含まれています。このサンプルを参考にすることで、CDKでダッシュボードを作成する方法を簡単に確認することができます。

The Destined Lambda パターン

EventBridgeの前にLambdaを配置してから処理をEventBridgeで振り分けるパターンです。

The Destined Lambda パターン

Lambdaを前段に置くことでEventBridgeと接続するために必要な固有の実装をDestined Lambdaに集約することができます。

またStep Functionsを使うほどではないが少し複雑なことがしたい場合に使えます。例えば処理を分岐させることでLambdaごとの処理を単純にしたり、EventBridgeで成功/失敗に応じて他のAWSサービスにイベントを送ったりすることができます。

The Dynamo Streamer パターン

API GatewayからDynamoDBにイベントを送信して、DynamoDB StreamでLambdaを実行するパターンです。

The Dynamo Streamer パターン

基本的なAPI Gateway->Lambda->DynamoDBで書き込むパターンでも同じ処理はできますが、異常が発生した場合にDLQに処理を送ったりしなければイベントが消失してしまいます。そこでDynamoDBにイベントを一度格納することで、イベントの消失を防ぐことができます。

参考URLの本筋とは外れますが、API Gateway->DynamoDBの実装パターンなのでLambdaレスサーバーレスをCDKでやりたい場合にも参考になるかと思います。

The EFS Lambda パターン

LambdaからEFSにアクセスしてファイルのデータをGET、POST、DELETEするパターンです。

The EFS Lambda パターン

S3を使う場合と比べると、大量のデータをLambdaでロードしたい(機械学習のモデルなど)場合に/tmp領域が512MBまでとなる制限を回避して処理することができます。その他の利点などは以下の記事でまとまっています。

The EventBridge ATM パターン

Lambdaから来たイベントをEventBridgeのRuleに基づいて振り分けるパターンです。例としてATMシステムが実装されています。

The EventBridge ATM パターン

イベントのルーティングを集中して管理できるので、マイクロサービス間でイベントを送受信する窓口が分かりやすくなります。

The EventBridge Circuit Breaker パターン

LambdaのエラーをEventBridgeに送信して処理することでサーキットブレーカーを実装するパターンです。以下の図はクローズされるまでの流れを表しています。

The EventBridge Circuit Breaker パターン

LambdaがExternal ServiceのAPIなどを利用していて、External Serviceがダウンしてしまった場合に、エラーイベントをEventBridgeに投げておきます。エラーが閾値以上になった場合は、LambdaからExternal Serviceへのアクセスを停止し、リクエスト元へ即座にエラーを返すようになっています。

上記により、LambdaがExternal Serviceを無駄に呼び出す実行時間分の料金を節約したりすることができます。また即座にエラーが返るのでエンドユーザも必要以上にエラーを待つ必要がなくなります。

The EventBridge ETL パターン

S3からデータをロードしてEventBridgeで処理をLambdaに振り分けてETLを実行するパターンです。大きめのデータのロードを想定して、S3からのデータロードにはFargateが使われています。

(注意:本番で使用する場合は、SQSによるエラー時の復元処理やKMSによる暗号化を考慮してください)

The EventBridge ETL パターン

自分個人としてETLを使用したことがないので深いことは書けないのですがAWS GlueなどETLサービスと比べると細かいチューニングはできるので既存のサービスが要件を満たさない場合は使用しても良いかもしれないです。

The Lambda Power Tuner

SAR(Serverless Application Repository)のaws-lambda-powertuningツールを作成して、Lambdaの性能をチューニングできる実装です。

The Lambda Power Tuner

チューニングツールを使うことでLambdaの実装に対してどのメモリ容量が一番コストパフォーマンスが高いか確認することができます。ツールの詳細や使用方法は以下の記事などでも確認できます。

またSARのデプロイをCDKに組み込むことで色々なテンプレートにAWSリソースの記述が分散するのを防ぐことができます。

The Lambda Trilogy

以下に記載した3つのLambdaのパターンが実装されています。

  • The Single Purpose Lambda(1つの目的ごとに独立したソースで構成するパターン)
  • The Fat Lambda(複数の目的の処理を1つのソースでまとめて実装するパターン)
  • The Lambda-lith(Expressなどを使って1つのLambdaで処理を振り分けるパターン)

The Lambda Trilogy

リンク先の中でそれぞれの実装の利点と欠点が語られているので、今までLambdaの実装を行ってきた方にも参考になるかと思います。

個人的にはサーバーレスアーキテクチャばかり触っているとThe Single Purpose Lambdaが最も良いと思ってました。ただ将来的にサーバーレスが廃れてしまうことを考慮した場合は、別のパターンも有りかと少しだけ思いました。

The RDS Proxy

LambdaからRDS Proxy経由でRDSのテーブル作成、データ挿入、データ抽出を実行する実装です。

The RDS Proxy

RDSを起動するためのVPC、セキュリティグループの作成など事前準備も実装に含まれているので、RDS Proxyをとりあえず試してみたい方におすすめです。

The Saga Step Function

マイクロサービスのSagaパターンをStepFunctionsで実装したものです。複数のLambdaなどにまたがる一連の処理が途中で失敗した場合、処理を打ち消すように補償トランザクションを実行します。

The Saga Step Function

Sagaパターンの詳細な情報は以下の記事やマイクロサービスの本などで紹介されています。

The Scalable Webhook

API Gateway+Lambda+SQSなどを用いてスケーラブルなWebhookを作るパターンです。

The Scalable Webhook

RDSに書き込む量を制限するために、中間の処理を挟んでいます。現在ならRDS Proxyを使うことでも解決できます。 ※ソース自体は簡略化のためにRDSをDynamoDBで代替えされています。

The Simple GraphQL Service

CDKからAppSyncを使ってGraphQLを実装するパターンです。

The Simple GraphQL Service

実装は現在StableなL1コンストラクトが使われています。まだExperimental VersionですがL2コンストラクトを使いたい場合はこちらの記事が役に立つと思います。

The Simple Webservice

シンプルにAPI Gateway->Lambda->DynamoDBでAPIを実行時にDynamoDBを更新する構成です。

The Simple Webservice

初めて実装する時はこのようなパターンから始めるのが良いかと思います。手動でWebコンソールから作成する場合と比べてロールなどが自動生成されるので簡単に始めることができます。

The State Machine

CDKでStepFunctionsを使っている設計です。

The State Machine

内容は基本的ですが、CDKでStepFunctionsを使う時の快適さが伝わりやすいと思うので、StepFunctionsを最初に触る際に使ってみるのが良いかと思います。

The X-Ray Tracer

DynamoDB、SQS、SNSなどとLambdaを繋ぐ際にX-Rayでトレースする方法がわかる実装です。

The X-Ray Tracer

ReadMeに詳しく動作確認する際の挙動などが書かれているので、X-Rayを導入する前に何ができるのか調査するために簡単に利用することができます。

所感

今後CDKが発展していく中で、このような基本パターンの実装は様々な会社や個人で行われることになります。

今回紹介したパターンを知っていることで、少しでも設計と実装の手間を減らせれば幸いです。

コントリビュートも歓迎されているようなので、時間ができたら自分も提案してPRを送りたいと思います。