キーポイント
-
サーバーレス・コンピューティングは、その本来の範囲を超えて進化しており、機能の一部または全部が汎用性の高いクラウド・コンストラクトに置き換えられ、クラウド・アーキテクチャの新時代の到来を告げている。
-
クラウド市場は、開発者のニーズに特化した独自のきめ細かい機能を提供する、高度で専門化した垂直マルチクラウドサービスへとシフトしている。
-
今後登場するクラウド・サービスは、ルーティング、フィルタリング、イベント・トリガーなどのタスクを処理する開発者の方法を変え、より効率的でユーザーフレンドリーなものにする、豊富なコンストラクトを備えている。
-
Infrastructure as CodeからComposition as Codeへと移行する大きなトレンドがあり、開発者は使い慣れたプログラミング言語を使用して、より直感的なクラウドサービスの設定ができる。
-
マイクロサービスはクラウドのランドスケープにおいて再定義されつつあり、単なるアーキテクチャの境界から組織の境界へと進化し、統一された開発者言語の下で様々なクラウドコンストラクトを統合している。
[注:この記事中の意見や予測は筆者のものであり、InfoQのものではない。]
AWS Lambdaが今年10周年を迎えるにあたり、サーバーレスコンピューティングは単なるFaaS(Function as a Service)にとどまらない広がりを見せている。今日では、サーバーレスとは、手動でのプロビジョニングが不要で、オンデマンドの自動スケーリングを提供し、消費ベースの価格設定を使用するクラウドサービスを指す。このシフトは、クラウド・コンピューティングにおけるより広範な進化の一部であり、サーバーレス・テクノロジーは継続的に変化している。この記事では、サーバーレスの先にある未来に焦点を当て、クラウドのランドスケープが現在のハイパースケーラ・モデルを超えてどのように進化していくのか、そしてそれが開発者や運用チームに与える影響を探る。この進化を形作る上位3つのトレンドについて考察する。
"プリミティブ開発"から、"Constructs as a Service"へ
ソフトウェア開発において、「モジュール」または「コンポーネント」は通常、まとまった一連の動作を示す自己完結型のソフトウェアの単位である。このコンセプトは、仮想マシン(VM)やコンテナサービスのような長時間稼働するコンピュートサービス上で実行されるマイクロサービスアーキテクチャにぴったり対応している。AWS EC2は、広くアクセス可能な最初のクラウドコンピューティングサービスの1つで、スケーラブルなVMを提供していた。このようなスケーラブルでアクセス可能なクラウドリソースを導入することで、マイクロサービスアーキテクチャが実用的かつ広く普及するために必要なインフラが提供された。このシフトは、モノリシックなアプリケーションを独立してデプロイ可能なマイクロサービス単位に分解することにつながった。
このソフトウェア単位のアナロジーを続けよう。関数は、定義された入力と出力で1つのタスクを実行する一連のステートメントをカプセル化したコードのブロックだ。このコードの単位は、FaaS実行モデルにうまく対応している。インフラを管理する必要なく、イベントに応答してコードを実行するFaaSの概念は、AWS Lambda以前から存在していたが、広範な実装と認知に欠けていた。
インフラを管理することなく、イベントに応答してコードを実行するFaaSのコンセプトは、AWS Lambdaが主流になる前に、Google App Engine、Azure WebJobs、IronWorker、AWS Elastic Beanstalkといったサービスによってすでに提案されていた。Lambdaは、FaaS初のメジャー商用実装として登場し、開発者のデプロイプロセスを容易にすることで、その普及の触媒として機能した。この進歩により、マイクロサービスはより小さく、個別にスケーラブルで、イベント駆動型のオペレーションへと変化した。
サービスとして提供されるより小さなソフトウェア単位への進化の中で、式やステートメントのような基本的なプログラミング要素がサービスとして提供されるようになるのだろうかと思うかもしれない(int x = a + b;のようなもの)。しかし、進歩はこの道から遠ざかっている。その代わりに、関数の最小化が進み、最終的には設定可能なクラウド・コンストラクトに取って代わられることになる。ソフトウェア開発におけるコンストラクトは、条件文(if-else、switch文)、ループ(for、while)、例外処理(try-catch-finally)、ユーザー定義のデータ構造といった要素を含み、プログラムの流れを制御し、複雑なデータ型を管理するのに役立つ。クラウドサービスでは、コンストラクトは分散アプリケーションの構成、マイクロサービスや関数などのソフトウェアモジュールの相互リンク、およびそれらの間のデータフローの管理を可能にする機能と連携する。
クラウドコンストラクトは関数に取って代わり、マイクロサービスに取って代わり、モノリシックアプリケーションに取って代わる。
以前は、関数を使用して、イベントのフィルタリング、ルーティング、バッチ処理、分割、別のクラウドサービスや関数の呼び出していたかもしれないが、現在では多くの場合、関数のコードを減らす、あるいは関数のコードをまったく使用せずに、これらを実行できる。これらの操作は、クラウドサービスの一部である設定可能なクラウドコンストラクトで置き換えることができる。Lambda関数コードからクラウドコンストラクトへの移行を実証するために、AWSからいくつかの具体例を見てみよう。
-
リクエストのルーティング - リクエストを解析し適切なバックエンドエンドポイントにルーティングする際に、Lambdaを使うのではなく、API Gatewayルートがルーティングを行うことができる。それだけでなく、API Gatewayは他のAWSサービスとも統合しており、それらを直接呼び出すことができるため、関数が不要になる。
-
リクエストの検証 - API GatewayはOpenAPIを使って、ボディ、クエリー文字列パラメーター、ヘッダーを検証できる。
-
データ変換 - API Gatewayは、Apache Velocityテンプレートを使用して、ペイロード、パラメータ、ヘッダー、ステータスコードをLambdaなしで上書きするようにリクエストとレスポンスのデータを変換できる。
-
データベースの変更をストリーミングする - DynamoDB Streamsはすべてのデータ変更をエミュレートする。これは、マイクロサービスを裏返しにすることで、アプリケーションコードとデータポーリングコードからの二重書き込みの必要性を取り除く、あらゆるデータストアに必須のコンストラクトとなる。
-
イベントトリガー - AWS Event Source Mappingは、イベントソースから読み込んでLambda関数を呼び出すことで、Lambdaをトリガーできる。
-
イベントフィルタリング - Event Source Mappingは、ストリームやキューからLambda関数を呼び出すレコードを制御するイベントフィルタリングを実行できる。これにより、関数内にフィルタリングロジックを記述する必要がなくなり、そのサイズとコストを大幅に削減できる。
-
イベントのバッチ処理 - 同じように、Event Source Mappingsはレコードを1つのペイロードにまとめてから関数に送信する。手動でループを回してイベントを集約したり、処理前にイベントを分割したりする必要はない。
-
イベントの変換 - EventBridge Pipesでは、ソースからのデータをJSONパス構文を使って変換してからターゲットに送信できる。
-
イベントのエンリッチメント - EventBridge Pipes は、リクエストを処理する前に、別のエンドポイントを呼び出してエンリッチメントできる。これはContent Enricherパターンの実装を提供し、完全に宣言的に使用できる。
-
イベント・ルーティング - リクエスト・ルーティングと同様に、EventBridgeルールでもイベント・ルーティングを行うことができる。
-
結果ベースのルーティング - Lambda Destinationは、非同期呼び出しが実行結果を他のAWSサービスにルーティングすることを可能にし、Lambda呼び出しコードを設定コードに置き換える。
-
他のサービスを呼び出す - StepFunctionタスクは、他のサービスや外部のHTTPエンドポイントを呼び出すためにLambda関数を必要としない。これにより、StepFunctionタスク定義は、例えばHTTP呼び出しやデータベースレコードの読み取り、更新、削除をLambda関数なしで実行できる。
これらは、アプリケーションコードの構成要素がサーバーレスクラウドの構成要素になるほんの一例に過ぎない。if-elseロジックで関数内の入力値を検証するのではなく、コンフィギュレーションで入力を検証できる。関数内から他のコードを呼び出すためにcase文やswitch文でイベントをルーティングするのではなく、関数外で宣言的にルーティングロジックを定義できる。イベントは、forループやwhileループのような繰り返しコンストラクトなしで、データ変更時にデータ・ソースからトリガーされたり、バッチ化されたり、分割されたりする。
イベントは、検証、変換、バッチ処理、ルーティング、フィルタリング、エンリッチメントを関数なしで実行できる。失敗は、try-catchコードなしで処理され、DLQに引き渡される。正常終了は、他の関数やサービスエンドポイントに引き渡される。これらのコンストラクトをアプリケーションコードからコンストラクトコンフィギュレーションに移行させることで、アプリケーションコードのサイズを縮小、あるいは削除し、セキュリティパッチやあらゆるメンテナンスの必要性をなくすことができる。
プログラミングにおけるプリミティブとコンストラクトには、それぞれ異なる意味と役割がある。プリミティブは、プログラミング言語固有の基本的なデータ型である。整数、浮動小数点、ブーリアン、文字などの基本的な値を表し、他の型は含まない。このコンセプトを反映するように、クラウドは、巨大なプログラミングランタイムのように、ネットワークロードバランサー、仮想マシン、ファイルストレージ、データベースといったインフラプリミティブから、より洗練され設定可能なクラウド・コンストラクトへと進化している。
プログラミングの構成要素のように、これらのクラウド・コンストラクトは分散アプリケーションのインタラクションを制御し、複雑なデータフローを管理する。しかし、これらのコンストラクトは孤立したクラウドサービスではない。スタンドアロンの「サービスとしてのフィルタリング」や「サービスとしてのイベントエミッター」は存在しない。「サービスとしてのコンストラクト」は存在しないが、ゲートウェイ、データストア、メッセージブローカー、関数ランタイムなど、コアとなるクラウドプリミティブの機能として不可欠なものになってきている。
この進化により、アプリケーションコードの複雑さが軽減され、多くの場合カスタム関数が不要になる。FaaSからNoFaaS(No fuss、シンプルさを意味する)へのこのシフトは、洞察に満ちた講演やGitHub上のコード例が公開されたりと、まだ始まったばかりだ。次に、垂直マルチクラウドサービスの中で、コンストラクトリッチなクラウドサービスの出現を探っていく。
ハイパースケールからハイパースペシャライゼーションへ
ポストサーバーレスクラウドの時代には、コンテナやファンクション用のコンピュートや、キーバリューストア、イベントストア、リレーショナルデータベースなどのストレージ・サービス、ロードバランサーなどのネットワークプリミティブのような、スケーラビリティの高いクラウドプリミティブを提供するだけではもはや十分ではない。ポストサーバーレスクラウドサービスは、開発者向けの構成が豊富で、アプリケーションの配管の多くをオフロードしなければならない。これは、広範なユーザーベース向けに汎用的なクラウドサービスをハイパースケーリングすることにとどまらず、より深く専門化し、より要求の厳しいユーザーに高度なコンストラクトを公開することを含んでいる。
AWS、Azure、GCPなどのハイパースケーラーは、その膨大なサービス群と広範なユーザーベースにより、新しいユーザーニーズと構造を特定するのに有利な立場にある。しかし、よりきめ細かな開発者コンストラクトを提供することは、結果として複雑さを増すことになる。どのサービスでも、新しい構成要素を効果的に利用するためには、その仕様について深く学習する必要がある。したがって、ポストサーバーレスの時代には、ある分野に秀でた垂直型のマルチクラウドサービスの台頭が見られるだろう。このシフトは、クラウドサービスのハイパースペシャライゼーション(超専門化)への動きを表している。
一例としてConfluent Cloudを考えてみよう。すべての主要なハイパースケーラー(AWS、Azure、GCPなど)がKafkaサービスを提供しているが、Confluent Cloudが提供する開発者の経験と構築に匹敵するものはない。Kafka ブローカー、多数の Kafka コネクタ、統合スキーマレジストリ、Flink 処理、データガバナンス、トレーシング、メッセージブラウザにより、Confluent Cloud はハイパースケーラーが提供するものを凌駕する、もっとも豊富なコンストラクトと特化した Kafka サービスを提供する。
この傾向は孤立したものではなく、MongoDB Atlas対DocumentDB、GitLab対CodeCommit、DataBricks対EMR、RedisLabs対ElasticCacheなど多くの例がある。既存のクラウド企業だけでなく、マルチクラウドのプリミティブな部分(特化したコンピュート、ストレージ、ネットワーキング、ビルドパイプライン、モニタリングなど)にフォーカスし、それを開発者向けコンストラクトでリッチ化することで、ユニークな価値を提案する新興企業も登場している。ここでは、単一のオープンソース技術に特化したクラウドサービスをいくつか紹介する。これは、豊富な構成エクスペリエンスを提供し、ハイパースケーラーからユーザーを引き付けることを目的としている。
-
Vercel:卓越したフロントエンド開発者エクスペリエンスで知られ、ウェブ・アプリケーションのデプロイを効率化する。
-
Railway:簡単なデプロイとスケーリング管理により、バックエンド開発者のエクスペリエンスを向上させる。
-
Supabase:Firebaseに代わるオープンソースで、同様の機能をより柔軟に提供する。
-
Fauna: 宣言型なリレーショナルクエリと、強整合性トランザクションにおける機能的なビジネスロジックで知られるサーバーレスデータベース。
-
Neon:もっともシンプルなサーバーレスPostgreSQLで、データベースの分岐や最小限の管理オーバーヘッドなどの機能を提供する。
-
PlanetScale:先進的なMySQLクラウドサービスで知られ、開発に適した機能に重点を置いている。
-
PolyScale:AIを活用したキャッシングに特化し、インテリジェントなキャッシングによってデータパフォーマンスを最適化する。
-
Upstash:イベントストリーミングに適したフルマネージドで低レイテンシーのサーバーレスKafkaソリューションを提供する。
-
Diagrid Catalyst:メッセージング、データ、ワークフローのためのサーバーレスDapr APIを提供し、クラウドサービス間の結合組織として機能する。
-
Temporal: 耐久性のある実行を提供し、複雑なワークフローを確実に管理するプラットフォームを提供する。
このリストは、ハイパースケーラーが提供するコアクラウドプリミティブの上に構築された、高度に専門化された垂直マルチクラウドサービスの成長エコシステムのごく一部である。これらのサービスは、プログラマブルなコンストラクトの包括的なセットと、開発者エクスペリエンスの向上を提供することで競争している。
サーバーレスのクラウドサービスは、豊富な開発者コンストラクトを備え、一つのことに特化している。
この移行が完了すれば、豊富なコンストラクトを持たないベアボーン型のクラウドサービスは、たとえサーバーレス型であっても、時代遅れのオンプレミスソフトウェアのように思えるだろう。ストレージサービスはDynamoDBのように変更をストリームしなければならない。メッセージブローカーは、イベント駆動型のルーティング、フィルタリング、リトライやDLQを使ったエンドポイント呼び出しのためのEventBridgeのようなコンストラクトを含むべきである。公開システムやサブシステムは、メッセージのバッチ処理、分割、フィルタリング、変換、および強化を提供する必要がある。
最終的に、ハイパースケーラーがサービスの種類を増やしながら水平方向に拡大する一方で、ハイパースペシャライザは垂直方向に成長し、単一のクラス最高のサービスをコンストラクトで強化しながら提供し、垂直方向のマルチクラウドサービスのエコシステムを形成する。将来のクラウドサービス競争は、インフラプリミティブから、コアとなるクラウドプリミティブと開発者中心のコンストラクトのデュオへと軸足を移すだろう。
インフラからコードとしてのコンポジション(CaC)へ
クラウド・コンストラクトは、アプリケーションとインフラの責任の境界をますます曖昧にしている。次の進化は、クラウド自動化の「シフトレフト」であり、ツールと責任の観点からアプリケーションと自動化コードを統合することだ。この移行がどのように展開されているかを見てみよう。
クラウドインフラストラクチャ管理の第一世代は、インフラのプロビジョニングと管理を簡素化するために登場したパターン、Infrastructure as Code(IaC)によって定義された。このアプローチは、クラウドコンピューティングにおける仮想化のコモディティ化によって確立されたトレンドに基づいている。
初期のIaCツールは、繰り返し可能な方法でクラウドリソースを作成、設定、管理することに特化した新しいドメイン固有言語(DSL)を導入した。Chef、Ansible、Puppet、Terraformなどのツールがこのフェーズをリードした。宣言型言語を活用したこれらのツールによって、運用チームはインフラストラクチャの望ましい状態をコードで定義し、根本的な複雑さを抽象化できるようになった。
しかし、クラウド環境が低レベルの粗いインフラから、より開発者中心のプログラマブルなきめ細かいコンストラクトへと移行するにつれて、これらの構成を定義するために既存の汎用プログラミング言語を使用する傾向が現れつつある。PulumiやAWS Cloud Development Kit(CDK)のような新規参入企業はこの波の最前線にあり、TypeScript、Python、C#、Go、Javaなどの言語をサポートしている。
汎用言語へのシフトは、クラウド構成をプログラムで定義するための表現力と柔軟性に欠ける宣言型言語の限界を克服する必要性と、クラウド構成の設定責任が運用から開発者にシフトしたことによるものだ。低レベルの静的インフラに適した宣言型言語の静的な性質とは異なり、汎用言語では開発者が動的でロジック駆動型のクラウド構成を定義できるため、アプリケーションコードとの緊密な連携が実現する。
インフラから開発チームへ、アプリケーション構成のシフトレフト
ポストサーバーレスクラウドの開発者は、関数やマイクロサービスを作成することでビジネスロジックを実装するだけでなく、プログラマブルなクラウド・コンストラクトを使用してそれらを組み合わせる必要がある。これにより、クラウドアプリケーションを開発し、構成するためのより広範な開発者の責任が形成される。例えば、Lambda関数にビジネスロジックを含むコードは、API Gatewayのルーティング、フィルタリング、リクエスト変換の設定も必要となる。
別のLambda関数では、特定のデータ変更をストリーミングするDynamoDBストリーミング構成、EventBridgeルーティング、フィルタリング、エンリッチメント構成が必要になるかもしれない。
第3のアプリケーションは、オーケストレーションロジックのほとんどをStepFunctionとして表現し、Lambdaコードは小さなタスクに過ぎないかもしれない。プラットフォームエンジニアでもOpsメンバーでもない開発者が、これらのコードユニットをまとめることができる。PulumiやAWS CDKなど、開発者が好きな言語を使って関数を実装し、同じ言語を使ってクラウド環境とのインタラクションを構成できるツールは、この時代にもっとも適している。
プラットフォームチームは、Terraformのような宣言型言語を使って、クラウド環境におけるチームの管理、セキュア化、監視、有効化できるが、開発者にフォーカスした構成は、開発者にフォーカスしたクラウド自動化言語と組み合わされ、クラウド・コンストラクトから離れ、クラウドにおける開発者のセルフサービスが現実のものとなるだろう。
DSLから汎用言語への移行は、IaCの進化における重要なマイルストーンとなる。この移行は、アプリケーションコードがクラウドコンストラクトに移行することを認識するものであり、多くの場合、アプリケーションのニーズに合わせて開発者がリソースをより深くコントロールする必要がある。この移行は、IaCツールの成熟を意味し、インフラオーケストレーションの幅広いニーズに対応する必要が出てきており、より洗練された高水準の抽象化とツールへの道を開いている。
インフラ管理は、静的なコンフィギュレーションから、より動的でコード駆動型のアプローチへと移行していくだろう。この進化は、Infrastructure as Codeにとどまらず、Composition as Codeと呼ばれる、よりニュアンスの異なる領域にも及んでいる。このパラダイムは、アプリケーションコードとインフラストラクチャの境界線をさらに曖昧にし、より合理的で効率的、開発者に優しいプラクティスをもたらす。
まとめ
トレンドとそれを補強する効果をまとめると、クラウドサービスへのプログラミングの統合が進んでいることがわかる。すべてのコンピュートサービスはCI/CDパイプラインを統合し、データベースはエッジからのHTTPアクセスを提供し、変更イベントを発行する。メッセージブローカーは、フィルタリング、ルーティング、べき等性、変換、DLQなどの機能を強化する。
インフラサービスは、サーバーレスAPI、コードから推測されるインフラ(IfC)、フレームワーク定義のインフラ、開発者が明示的に構成するインフラ(CaC)へと進化している。この進化は、より小さな機能、時にはNoFaaSパターンへとつながり、超専門化された開発者ファーストの垂直マルチクラウドサービスへの道を開く。これらのサービスは、インフラをプログラマブルなAPIとして提供し、開発者が好みのプログラミング言語を使用してアプリケーションをシームレスに統合できるようにする。
クラウドサービスを利用したアプリケーション構成のシフトレフトは、ますますアプリケーションプログラミングと融合し、マイクロサービスをアーキテクチャスタイルから組織的なものへと変化させるだろう。マイクロサービスは、もはや単一のデプロイメント単位やプロセス境界ではなく、開発者が選択した単一の言語で実装され、接着された、関数、コンテナ、クラウド構成のコンポジションになるだろう。未来は、超専門化され、開発者ファーストのクラウドに集中するようになる。