[レポート] AWS Lambda と Amazon API Gateway で安全なデプロイを行うためのベストプラクティス #awssummit

Guten Abend!ベルリンから伊藤です。

2019年2月26日〜27日にかけて開催されているAWS Summit Berlin 2019、本日2日目のセッションに参加しましたので、引き続きレポートをお届けします。

本記事は、Danilo Poccia 氏 (AWS) による Best Practices for Safe Deployments on AWS Lambda and Amazon API Gateway のセッションレポートです。

セッション概要

Deploying frequently is fundamental to reducing the feedback loop and increasing developer productivity. There are multiple features available in AWS Lambda, Amazon API Gateway, and AWS Serverless Application Model (AWS SAM) that you can use to implement a continuous deployment pipeline with safe deployment strategies, such as canary releases. In this session, we review the possible options applied to different scenarios, such as microservices architectures, chaos engineering, and A/B testing to discover the best practices for your use cases.

フィードバックループを減らして開発者の効率を上げるには、頻繁にデプロイを行うことが大事です。継続的デプロイを安全に行う、Canary リリースの導入に、AWS Lambda、Amazon API Gateway、AWS Serverless Application Model (AWS SAM) などがあり、セッションではこれらのユースケースを紹介していきます。

レポート

Infrastructure as code

  • インフラを繰り返し利用可能で予測可能なものに
  • 同じツールを使用してコード変更によってインフラ変更をリリース
  • 継続的なテストを行えるよう本番環境をステージング環境へレプリケート

  • アプローチ
    • Declarative (宣言型)
    • Imperative (命令型)

IaCにおける、一般的なコーディングのアプローチのようです。
(参考:Infrastructure as Code - Wikipedia

AWS Serverless Application Model (AWS SAM)

サーバレスアプリケーションのためのIaCとして、AWS SAMがあります。AWS Serverless Application Model (AWS SAM) とは、CloudFormationの拡張で、サーバーレスアプリケーションを開発するオープンソースフレームワークです。

  • SAM テンプレート

SAMのテンプレートを使って、たった20行でLambda関数、IAMロール、API Gateway、DynamoDB テーブルを作成するコードが記述できます。

こちらの記事で詳しく紹介されていました。

  • SAM CLI

SAM CLI はSAMテンプレートやアプリケーションコードを使用してアプリケーションをデプロイしたり(deploy)、アーティファクトをS3バケットへアップロードしたり(package)、Python、Node.js等をサポートするLambda関数を作成したり(build)、そしてLambda関数を呼び出したり(invoke)といったことができます。

参考:Github

実行の流れは次の通り。buildpackagedeployを繰り返すことで簡単にデプロイできます。

ユースケース

下記は、SNSの動きによって、何らかのアクションを起こす(Twitter のキーワードをキャッチして、それに応じて反応するなど)ケースの例です。

  • Standard Component: 一般的に広く使用されているコンポーネントを使用
  • Custom Business Logic: ニーズに応じてカスタマイズ

サーバレスデプロイメント

テスト環境と本番環境で、以下のような流れとなります。

  • SAM テンプレート + アプリケーションコード
  • Package
  • デプロイ
  • 開発/テストスタック
  • デプロイ
  • 本番スタック

CodeDeploy

SAMテンプレートでLamba関数のデプロイが可能です。ここでは、Canary リリースを導入しています。Canaryリリースとは、新しいバージョンをテスト目的で少しずつリリースしていく手法だそうです。下記のCanary10Percent10Minutesの場合は、10%のトラフィックを10分間新しいバージョンへ流し、その後100%を新しいバージョンへリリースされます。(参考ドキュメント:Gradual Code Deployment

こちらの記事でも詳細に説明されています!

  • API Gateway - Lambda関数 (エイリアス:"live") - Lambda コード (Version 1) で、Version 2 にCanaryデプロイメント
    • v1コードへ100%のトラフィックの状態からスタート
    • トラフィックを流す前にv2コードへPreTrafficフックを実行
    • 10%をv2コードへ流して10分間待機、エラーの際にはCloudWatchアラーム、アラームが鳴ったらロールバック
    • PostTrafficフックを実行してデプロイ完了

API Gateway 側でもステージで同様に Canary デプロイが実現できるようです。(参考ドキュメント:API Gateway Canary リリースのデプロイをセットアップする

Capital One の事例

  • DynamoDB をプライマリDWHとして使用
  • DynamoDB Streams で古いデータは自動的に削除するよう管理

  • 以前は労働時間外の特定日時でデプロイしていたものを、労働時間内で1日に2回といった頻度でデプロイできるように
  • LambdaでGoを使用して70%パフォーマンス向上(リクエストを受けた時間からレスポンスを送り返すまでの時間)
  • EC2、ELB、RDSをソリューションから外すことで、90% コスト削減
  • チームでの DevOps の時間削減、開発に集中することでチームの速度が30%増

デモ: store-and-reply

メッセージ投げるとその言語に従って応答し、データをDynamoDBに蓄積するというアプリケーションだそうです。

API GatewayのURLのパラメータでmessage=にいろいろな外国語で挨拶を送ると、それぞれの言語でメッセージが返されています。(※ボンジョルノ(イタリア語)の1つ目は、スペルミスにより英語が返されてます(笑))

DynamoDB側でもきちんと格納されていますね。

ここでコード内で返却されるメッセージを少し修正し、SAMテンプレートでデプロイ方法(DeploymentPreference)にLinear10PercentEvery1Minuteを指定しました。これにより1分ごとに10%、つまり10分かけてすべてのデプロイが行われます。

差分をgit pushすると、Code Pipelineにより自動的にSource→Build→Deployとデプロイが開始されます。

コンソールから CodeDeploy を確認すると、Linear10PercentEvery1Minuteを指定したため、3分経過して30%のトラフィックに新バージョンがデプロイされています。

この状況で何度か実行してみると、実際にいくつかは新しいバージョン、いくつかは古いバージョンのメッセージが返却されました。("Guten Tag aus Berlin!" が入ってる方が新しい方です。)

まとめ

いかがでしたでしょうか。
サーバーレスアプリケーションの安全なデプロイについてのセッションレポートを紹介しました。
ぜひご参考にしてみてください。

Gute Nacht!