Rのつく財団入り口

ITエンジニア界隈で本やイベント、技術系の話などを書いています。

【感想】『基礎から学ぶ サーバーレス開発』: AWS Serverless 2020 を知ろう

基礎から学ぶ サーバーレス開発

 タイトルに「AWS」が入っていませんが、AWSに限定してサーバーレス周りの開発の基礎を一通り解説した本。作者陣はCIerとしても有名なアイレット社の方々。JAWS-UG運営の方もいらっしゃいますね。そういえば2019年のAWS Summitに行った時にcloudpackのノベルティをもらった覚えがあります……

CHAPTER01 サーバーレスとは

 2014年に提供開始されたAWS Lambdaの登場で大きく変わった、サーバーレスとは何ぞやという話。注目を浴びている一方で本書では課題も上げています。

  • サーバー運用の負担は減るが、機器構成の自由度が オンプレ>IaaS>サーバーレス
  • 同時実行数や実行時間に制限がある
  • 各マネージドサービスをちゃんと組み合わせて要件を満たすシステムを構築する設計能力がないと、逆効果の場合もある

サーバーレスのメリットについては以下を挙げています。

  • コストが大幅低減される
  • EC2と違いオートスケールしてくれる
  • OS以外にもWebサーバー、プログラム言語などミドルウェアのメンテが不要になる
  • その時間をアプリ開発に集中できる
  • Lambdaは基本IPが公開されないので、サーバーへ攻撃されない
  • マイクロサービス開発にフィットする
  • 顧客も興味を持っている

最後のメリットはさすが現場のCIerさんの意見ですね。提案書に盛り込んだ新しいワードに食いつくお客さんというのはどこでもいそうです。

aws.amazon.com

サーバーレスのデメリットとしては以下を挙げています。

  • Lambdaは同時実行数1000、タイムアウト15分など仕様上の制約がある
  • ステートレスな構造が設計必須:一時ファイルは持てない、S3へ登録必須など
  • 監視が複雑になる:起動しなかった場合のリトライなど
  • AWS障害で影響を受けた時、即時対応できない場合もある(問い合わせて対応を待つしかない等)
  • ミリ秒単位の応答を求められる用途に向かない:コールドスタートは0.*秒~数秒かかる
  • 24時間稼働や常にリクエストが飛び続けるシステムには向かない
  • 言語やライブラリのバージョンアップは開発者側担当なので、リリース後のメンテの仕組みの検討が必要
  • モノシリックなシステムには不向き
  • LambdaからODBC接続でRDSに繋げるとコールドスタートで数秒~数十秒かかることも(2019/9より昔)。同時接続数もAurora Serverlessだと最小構成なら90しかない。同時実行数1000の中で間に合っていてもこの90で引っかかったりする

 最後のLambdaからRDSへ繋げるのはかつてはアンチパターンとしても知られていたそうです。Lamdaを使った構成の実例というと大抵後ろにはRDBでなくてDynamoDBがいるのには、こういう訳があるのですね。
技術はなんでもそうですが、闇雲に使えばいいという訳ではないというあたりもしっかり書いています。

docs.aws.amazon.com

CHAPTER02 サーバーレス開発でよく使うサービス

知っている方にはおなじみな、だいたいよく出てくるサービスの機能をまとめている章。

  • AWS Lambda: 2019年のVPC設定のアップデートで起動時間は改善。ランタイム(言語)はNode.js/Java/Python/Go/.NET Core/Rubyが標準で用意。「.NET 5」は2020/11リリースなのでLambdaではまだ.NETCore。
  • Amazon API Gateway: 後ろがコンテンツでなくLambdaなどの場合も、CloudFrontと組み合わせてレイテンシーを抑えられる。WebSocket APIを使うとステートフルな通信でチャットアプリなどにも使える。
  • Amazon Aurora Serverless: 名前が超ややこしいが、サーバーレス専用のまったく新しいAuroraではなくてスケーリングを自動でやってくれるオプション。アクセスがあった時だけお金がかかる。使用頻度が低かったり、インスタンスサイズが不明だったりワークロードが予想できなかったり、ピーク時期が決まっているもの、開発用で平日昼間しか使わないものなどに使える。

docs.aws.amazon.com

  • Amazon CloudWatch: 2018年のre:Inventでクエリ言語を使ってログ内の検索や分析ができる CloudWatch Logs Insights が登場、だいぶ便利になった。

docs.aws.amazon.com

  • Amazon SQS: 性能の良い標準キューと、順番が保証されるFIFOキューがある。
  • AWS CodeCommit: ユーザ5人までだと制限内では実は無料。
  • AWS CodePipeline: リリースまでのステップ作業を自動化。

docs.aws.amazon.com

  • AWS CodeBuild: ビルド時は内部でマシンを使うのでAmazon LinuxUbuntu。東京リージョンでは使えないが、Windows Server 2016 も使えるリージョンもある。
  • AWS CodeDeploy: Lambdaのデプロイの場合は3種類。All at onceの全部一度、Y分ごとにXパーセントづつの「線形」、Xパーセント移行の後にY分後に残り全部を変えるのが「カナリア」。
  • Amazon S3: 機能いろいろ。AWS認定でもよく出るやつ。
  • AWS Step Functions: 2016年の登場時はLambda専用のワークフロー管理だった。2020現在は連携できるサービスがかなり増えて便利に。2019年発表の Step Functions Express Workflow はIoTなど短時間の大量イベント処理向けに最初から設計、制限や違いがあるが値段もお得。

docs.aws.amazon.com

  • AWS DynamoDB: WCU/RCUのキャパシティユニットは、最初から設定するプロビジョニング済み以外にオンデマンドもある。

  • AWS Cloud9: ブラウザで動くIDE。実はEC2上以外にオンプレでもインストールできる。SAMをサポートしていてサーバーレスでよく使われる。

docs.aws.amazon.com docs.aws.amazon.com

  • AWS X-Ray: 2016年登場。Lambdaのコードに所定のX-Ray SDK組み込み用コードを書くと、グラフィカルに表示。無料枠もある。

docs.aws.amazon.com

 自分的にはAWS認定試験でよく出てきたやつ!と思いきや、けっこう新しくなっているサービスもありました。どんどん進化していきますね……

CHAPTER03 サーバーレスアプリケーションの構築

 実際の構築の章。フレームワークは2つあります。
SAM: Servlerless Application ModelAWS専用の構築用フレームワーク

  • AWS SAM CLIをドキュメントに従ってローカルにインストール。
  • > sam init でクイックスタートテンプレートを選んでいって選択、ディレクトリが作られる。
  • アプリのディレクトリに移動して > sam build でビルド。出来上がった生成物を「アーティファクト」と称する。
  • > sam local invoke でローカル上でLambdaも実行できる。
  • > sam deploy (--guided) で対話形式で選んだりしてデプロイ。内部的にCloudFormationが使われ、AWS上にLambda関数のリソース実物が登録される。
  • その後は curl コマンドなどでAWS上のURLにリクエストを投げて確認。
  • > sam local start-api で、ローカル上にDockerを使って環境が作られるので、curl http://127.0.0.1:3000/hogehoge のような指定でも動く。
  • リソースの削除はコマンドがないので、AWS CLIのコマンドで > aws cloudformation deelte-stack ... のようにCFnを使って削除。

aws.amazon.com docs.aws.amazon.com

Serverless FrameworkAWSサービスへの連携度は落ちるが、Google Cloud FunctionsとAzure Functions でも動く汎用的なもの。プラグインが豊富なんだそうです。

  • > sls create --template xx --name AppName のようにしてディレクトリ作成。設定ファイルはserverless.yml
  • > sls deploy がデプロイ。
  • > sls invole local --function funcName のようにしてローカル実行。
  • SAMと違って > sls remove でリソースを削除できる。

www.serverless.com www.serverless.com www.serverless.com

フレームワーク」と名付けられていますがRailsやLaravelやDjangoのようなWebアプリケーションフレームワークとはだいぶ意味が違って、フロントエンドの技術ならボイラープレート、create-react-appやVue CLIなどなどにちょっと似てます。コマンドでいろいろできて設定も補助してくれる便利ツールのような印象です。

 CI/CDについても2章で出てきたCodeシリーズを使った一連の流れの実例を詳しく説明しています。パイプラインで使うリソースの用意の設定ファイルはpipeline.xml, CodeBuildの設定はbuildspec.yml でした。(これは認定試験でよく見たやつ...)
デプロイ時にトラフィックを切り替える「トラフィックシフト」についてもLambdaのバージョニングを利用した通常/カナリアリリースでの実例を挙げています。この節はエイリアスの説明があまりなかったので自分的にはちょい分かりにくかったです。

https://d1.awsstatic.com/International/ja_JP/Whitepapers/practicing-continuous-integration-continuous-delivery-on-AWS_JA_final.pdf

CHAPTER04 サーバーレスの運用・監視

 まずは一見するとEC2の上位互換のようにも見えるサーバーレスで、どれだけコストが変わるかの話。

  • 1日に1万リクエストを受けるLambda関数で約0.2ドル/月 (21円)
  • 秒間10リクエストで1日86万余りに量が増えると...約16ドル/月 (1670円)
  • 同時実行数の上限、秒間1000リクエストだと一か月で8640万リクエストの高負荷...それでも約53ドル/月(5520円)。EC2インスタンスは一番安いのは月5ドル、高いのでも91ドルでたいていサーバーレスの方が安い。
  • しかしLambda関数の実行時間が1回1sまで伸びてしまうと……約197ドル/月(2万円超え)。実行時間が後からどんどん増えるような処理は要注意。
  • 5分ごとに起動して処理に5分もかかる激重バッチ処理をLambdaで実現しメモリも最大限の3GB割り当て...216ドル/月(6.7万円!!)

 うーん月6-7万というと家賃みたいですね。業務システムにLambdaを適用するとなるとバッチに使ったりするのかなと何となく思っていたのですが、必ずしもそういう訳でもなさそうです。本書でも強調されていますが、他の手段と比較し、システムの要件に合わせて検討していく必要があるのですね。

サーバーレスの監視についても以下のように解説しています。

  • サーバーレスはイベント駆動で実行、リソース同士も疎結合になるので、原因箇所究明の時などに繋がりが直感的に把握しにくい課題がある。AWS X-Rayを使うと可視化と診断が可能。
  • ホスト上のシステムでは高可用性や冗長構成などインフラ回りも整備して監視が必要だが、サーバーレスになるとAWSに任せられるのでそこは楽。
  • EC2のメモリ利用量はAmazon CloudWatchのカスタムメトリクスで採れたが、LambdaだとCloudWatch Logsの実行レポートから見るしかない。このように逆に手間が増える場合もある。
  • 最初にどのように運用するかの検討が大事。
  • サービスが適切に提供できているかの観点で監視し、リソースの状態を確認する。
  • Lambdaの実行時エラーの監視では、イベント型が同期呼び出し/非同期呼び出し/ストリーム型それぞれでリトライが違うのに注意。
  • Lambda関数にデッドレターキューが実装されてから(2016-)は、非同期呼び出しでも実行失敗時にSQSに通知したりできるようになったが、その前は大変だった。このように機能追加によってやり方が変わることもある。

CHAPTER05 サーバーレス開発におけるセキュリティ

 クラウドベンダーに任せればOKではなくて、セキュリティ対策も必要ですというお話の章。

  • 先頭にWAFを設定して防御、CloudFrontを通してその後ろにAPI Gatewayがあって対策は十分……のように見えて、API GatewayのURLを直接叩いて攻撃するパターンもある:CloudFrontからHTTPヘッダにX-API-Keyを追加し、これがないと奥のAPI Gatewayを通過できなくする。
  • WAFのルールの最新化が間に合わず攻撃が通ってしまう場合もある:奥のLambda関数のコードはデプロイする前にレビューする。
  • API Gatewayはデフォルトが認証機能OFFになっているのに注意(!)。 とりあえずデプロイすると全世界に無防備に公開されてしまう。
  • 秘密情報の保護はSecrets Managerが高性能だが高い。Parameter StoreはDB認証情報は手動更新になったりするが、本体は無料。
  • AWSアカウントのセキュリティ設定も重要。
  • セキュリティ周りのサービスはAWS Trusted Advisor, Amazon GuardDuty, AWS CloudTrail, Amazon CloudWatch, AWS Config。

 CloudFrontをリクエスト/レスポンスが通る際、振る舞いとしてCloudFrontの中にデプロイしたLambda関数が動作する機能が「Lambda@Edge」。これを使った実例も挙げています。立ち位置としてはCloudFrontの機能の一つなんですね。(自分も最初は別のサービスかと誤解してました……)

  • S3にHTMLファイルを置いて静的ウェブサイトを作る構成だと、URL末尾が https://edge.com/ のアクセスではindex.htmlを返してくれない弱点がある(!)。 これを解決する。
  • S3にはindex.htmlを登録。
  • ロールを作り、Lambda関数を作成。リクエストのURL末尾が/だったら/index.htmlに変えて戻すだけ。サンプルコードはJavaScript
  • 画面からLambda@Edgeへデプロイ。CloudFrontディストリビューションを選んで、CloudFrontイベントは「オリジンリクエスト」を選ぶ。
  • 応用で別のLambda関数で、レスポンスのヘッダーに各種セキュリティヘッダーを加えるコード例。こちらはデプロイ時にCloudFrontイベントで「オリジンレスポンス」を選ぶ。
  • なお東京リージョン(ap-northeast-1)では使えず、バージニアリージョン(us-east-1)で作成するしかない。

CHAPTER06 サーバーレスの構築例

 実際の開発イメージが分かる構築例が、豊富なスクリーンショットと共に掲載されています。

完全サーバーレスでのWebページ構築事案

HTMLや画像はすべてS3に上げて静的Webサイト。データはLambda関数を通して後ろのDBのAurora Serverlessから取ってくるという構成での構築例。

  • Lambda関数をVPC内に配置するので、Elastic IPを取得する。(これをしないとLambdaには固定IPがない)
  • よくあるチュートリアルのようにVPC内にサブネットを構築、マルチAZに割り当て。
  • API Gateway→Lambda用にセキュリティグループを作成。ポート443を許可。
  • VPC内のRDS用のセキュリティグループを作成、ソースで上のLambda用のセキュリティグループを割り当て。
  • RDSのデータベースの作成でAuroraを選び、オプションでサーバーレスを選び、Data APIを有効に。これでコンソール画面からSQL実行可能に。
  • データベースのパラメーターグループを新規に作成、日本語にしてタイムゾーンをAsia/Tokyoにし、DBに適用。これで日本語が使えるようになる。
  • 管理コンソールからAuroraに繋げてcreate table文とinsert文を発行、テストデータ作成。
  • Lambda実行用のロールを作成。[ユースケースの選択]の中に用意されている。
  • ローカルの作業ディレクトリで、RDSに繋げてselect文を発行するLambda関数作成。サンプルコードはPython3.8。
  • 作業ディレクトリごとzipに固め、管理コンソールのLambdaの画面からアップロード。ロールを指定し、Lambdaの環境変数にDB接続先を設定。
  • Lambdaの設定で、RDSがあるVPCとサブネットを指定。これでLambda関数とRDSが繋がるようになる。
  • GETリクエストでこのLambda関数が呼ばれるAPI Gatewayを新規作成して公開。
  • このあとcurlコマンドでURLにGETを飛ばすと、検索結果がJSONの集合で返ってくる。

 続いて、マスターデータがオンプレミスの他社サーバー上のCSVにあり、これを取ってこなければならない……というケース。こんな時に使うサービスもあるんですね。

  • オンプレサーバーにSFTP(=SSH)接続してS3とファイルを直接転送できるフルマネージドなサービス、AWS Transfer for SFTP を構築。管理コンソールでボタンを押すとサーバーが構築される。
  • 秘密鍵と公開鍵をローカルで作る。公開鍵の内容はコンソールにコピペして設定する。
  • S3バケットとIAMポリシーを作っておく。
  • > sftp ... {作成したSFTPサーバーのエンドポイント}のようにコマンドで接続、put {ファイル名} とするとS3バケットにファイルが転送される。
  • 秘密鍵はSecrets Managerにコマンドで登録して、生成されるARNを控えておく。
  • バッチ処理用のLambda関数を作る。実行ロールに先ほどのARNを指定。Pythonの場合はparamikoという外部モジュールがあるとSFTPサーバーに繋げられる。
  • コードの中身はSecrets Managerから秘密鍵をダウンロードしてssh接続、CSVファイルを取得して内容を読みこみ。Aurora上の―ブルにinsert文を発行して書き込んでいくもの。
  • 最後に管理コンソールのCloudWatchからイベントを選んでいって、定時に起動するようcron式を設定。これがCloudWatch Events。
  • そしてSFTPサーバーは1時間0.3ドル(31円)もかかってしまうので不要な時は停止。
  • Lambda関数の実行は15分以内なのでバッチもこの期間内。もっと大きい場合は分割してStep Functionsにしたり、Fargateを使ったりする。

 このAWS Transfer for SFTPですが、現在は他の機能も加わってサービス名としては「AWS Transfer Family」となっているようです。 aws.amazon.com

APIバックエンドにRDSを用いた事例及び2019年のアップデートについて

 上の構築事例でも出てきますが、LamdaをVPC内のサブネットにアタッチする方法を改めて詳しく説明しています。「VPC Lambda」と呼ぶんですね。(サービス名ぽくてややこしいです...) 2019年に改善されたアップデートは3点でした。

  • ENI作成タイミング変更:ネットワークインターフェースのENI。従来はLambdaがコンテナから起動してコールドスタートする時にENIの紐付が行われており、最大60秒。API Gatewayタイムアウト29秒を超えてしまうことがよくあった。ENI作成タイミングが最初のLambdaデプロイ時に変わることで解決。
  • Provisioned Cuncurrency: 突発大量リクエストの際にLambdaのコールドスタートで遅くなるのを防ぐため、予め指定された数のLambdaを起動しておけるように。設定数は要調整、また無料利用枠から外れてしまう。
  • RDS Proxy: Amazon RDS側の新機能。接続先をプロキシに紐づけておくと、不要セッション管理などをプロキシに任せられる。これのおかげでLambda→RDSで繋ぎまくってDBコネクションが枯渇する現象に対応できるように。

 このアップデートで、もはやアンチパターンでもなくなって活用の幅が広がったとのこと。自分のいるエンタープライズな開発の世界だと、たとえこれからAWSがより使われるようになっても、データの置き場所はDynamoDBではなくオンプレのRDBからデータを移行した各種RDSであることが多そう(な気がする)ので、こういう最新情報にも触れてくれるのはありがたいですね。

aws.amazon.com

aws.amazon.com

サーバーレスで作る在宅勤務中の勤務時間登録システム

 2017年に発表された「AWS IoTエンタープライズボタン」を活用して、物理的なボタンを押したらLambda関数が動いてSlackに通知、Google Apps Script(GAS)経由でGoogleスプレッドシートに勤怠を記入するという、withコロナ時代っぽい仕組み。実際に活用されているそうです。

docs.aws.amazon.com

  • JavaScriptでLambda関数作成。後半のイベントが起動処理の模様。シングルクリックでないことを判定して、分岐してSlackへのPOSTとGASへPOST。通信先のURLが入っている環境変数は暗号化している。
  • AWS Key Management Serviceを使い、暗号化のキーを新規作成。
  • 環境変数の設定画面で、暗号化したい環境変数に上のキーを指定して暗号化。
  • 受信するSlack側では、手軽に実現できるAppでIncoming Webhookを選んで追加。チャンネルを選んで得られたWebhook URLをLambda側に設定。
  • GAS側で受信後に実行される処理もJavaScriptっぽいGASで記述、スプレッドシートに貼りつけてウェブアプリケーションとして導入する。URLが生成されるのでこれもLambda側に設定。
  • AWS側ではAWS IoT 1-Clickというのを使い、デバイスを登録、プロジェクトを作り、アクションでLambdaを選ぶ。
  • プロジェクトの設定で物理ボタンを紐付て、あとは動かしてレポートを確認。
AWS LambdaをAlexaのエンドポイントとして使う事例

 最後はGUIでなくて声が入力のVUIとして、Alexa経由でTodoリストを作ってしまうという本格的な例。

  • 保存先はDynamoDBにしてフルアクセス。
  • Lambdaのコード例はここもJavaScript。各処理に対応したHandlerを書いていく。Alexaからはslot経由でデータがとれる。
  • WebのAlexaの画面でログインして「スキル」を作っていく。画面でJSONエディターが開くので、Alexaに喋らせる諸々を設定。
  • 同じように画面からLambda関数と紐づける。
  • 完全ビルドが終わると、マイクで喋るとAlexaから返事が返ってくる。

developer.amazon.com

 最後のこの事例は非常に本格的で、Lambdaのコード例がけっこう長くて理解しきれませんでした(笑)

CHAPTER07 サーバーレスの失敗談と問題解決

 最後は先駆者の失敗のありがたい共有ということで、スクショ付きで幾つか載っています。

  • Amazon RDSを止めるのを忘れて費用請求が大変なことに!:→Aurora Serverlessは、DBへの接続がないとデフォルト5分で自動で停止し、色々設定変更可能。ちなみに起動は30秒~1分かかってしまう。フロントエンド側でのリトライ処理や、CloudFront/API Gatewayのキャッシュ活用がいる。
  • S3を処理するLambdaの入力と出力の宛先バケットを間違えて一気にスロットリング!:→Lambda起動のイベント対応は「すべてのオブジェクト作成イベント」でなく絞る。同時実行数も1にする。
  • Nuxt.js製のSPAを作ってS3にアップロード。存在しないURLを選択するとローカルならふつうに404エラー。しかしS3上だとAccess Denied(403 Forbidden):→S3バケットを公開設定にしていないと、そのURLに対応したS3オブジェクトを見に行こうとするから。CloudFrontのエラーレスポンスのカスタマイズで、403の時は/index.htmlに戻るようにする。

自分が使うシーンが出てこないことを祈りたいところですが、Lambda関数が無限ループしたら、管理コンソールの「スロットリング」ボタンで強制停止するというテクもあるんですね。
本書のあちこちに出てきますが、配置した後の監視もけっこう大事なのだなと思いました。

まとめ:AWSのサーバーレス開発の今が概観できる本

 この先詳しくはAWS公式へ、となっているところもありますが、サーバーレス周りの情報を一通り掴める本でした。
さすがにクラウドの現場の会社発ということで、気を付けるべき点や思わぬ実戦テクもあちこちに書いてありますし、設定例やLamda関数のコード例も豊富です。258ページなので割と手軽に読めます。
 ありがたいのは本書は2020年7月刊行、2020年前半までのAWSアップデートが反映されているところ。下に並べてみましたがサーバーレスの本というと2017-2018年頃で止まっているので、最新情報が得られるのは助かります。
僕もAWS認定資格の知識がベースだったもので、なんかもう新しくなってる……!という箇所があちこちにありました。Lambdaの後ろにRDSを配置するのは以前はアンチパターンだったなんて本書で初めて知りました。
 既にサーバーレスの地平に身を置いている方にも、学習中の方にも、それぞれ役に立つことと思います。自分的にはやはりコードを書くエンジニアなので、Lambda関数周りはさらに深堀っていきたいなと思いました。

f:id:iwasiman:20201211111444p:plain

おまけ:サーバーレスを扱った本

AWSによるサーバーレスアーキテクチャが原著者はServerlessconfのオーガナイザーの方で翻訳が2018年。この本はよく見聞きします。

AWSによるサーバーレスアーキテクチャ

AWSによるサーバーレスアーキテクチャ

  • 作者:Peter Sbarski
  • 発売日: 2018/03/14
  • メディア: 単行本(ソフトカバー)

Amazon Web Servicesを使ったサーバーレスアプリケーション開発ガイド』が同じく2018年。AWSJの中の人自らによる執筆。

AWS Lambda実践ガイド』が2017年10月、LambdaにフォーカスしてコードはすべてPython。評価の高い本です。

AWS Lambda実践ガイド

AWS Lambda実践ガイド

その後読んで感想も書いたのですが、2017年刊行でもそう古いところはなく、2021年現在でも十分役に立つ本でした。

iwasiman.hatenablog.com

『実践AWS Lambda 「サーバレス」を実現する新しいアプリケーションのプラットフォーム』 も同じく2017年の6月、こちらはAWSJの方による執筆で日本で最初のLambdaの本。

『サーバーレスシングルページアプリケーション ―S3、AWS Lambda、API Gateway、DynamoDB、Cognitoで構築するスケーラブルなWebサービスがタイトルが長いオライリーの翻訳本で2017年。フロント側のSPAまで扱っています。

ほか、技術の泉シリーズの軽めの本やKindle限定の本でいくつかあります。

AWS以外のクラウドプラットフォーム、AzureやGCPでかつサーバーレスの本というのは商業本では出ていませんが、AWS Lambdaに相当するAzure Functionsに限った本は2019年に出ています。