Amazon Web Services ブログ

Web アプリケーションの AWS サーバーレスへのリフト & シフト : パート 1

この記事は Marcia Villalba によって投稿された Lifting and shifting a web application to AWS Serverless: Part 1 を翻訳したものです。

クラウドに移行するお客様は、多くの場合、サーバーレスアーキテクチャのメリットを享受したいと考えています。しかし、最善のアプローチは何か、そしてそれは可能でしょうか? 移行にはさまざまな戦略がありますが、移行したワークロードを本番環境に移行するには、リフト & シフトが最速の方法であることがよくあります。

また、従来の環境で実行されている既存のアプリケーションをサーバーレスにリフト & シフトできるかどうか疑問に思うかもしれません。この記事では、 MongoExpressReact および Node.js (MERN) スタックの Web アプリでこれを行う方法を説明しています。ただし、この記事で紹介した議論は他のスタックにも当てはまります。

リフト& シフト移行を行う理由

リフト & シフトはアプリケーションのリホストと呼ばれることもあります。これは、可能な限り少ない変更でアプリケーションを移行することです。リフト & シフト移行では、多くの場合、新しいワークロードをできるだけ早く本番環境に移行できます。サーバーレスに移行する際、リフト & シフトにより、まだクラウドやサーバーレス環境になっていないワークロードを、マネージドサービスやサーバーレスサービスを迅速に使用できるようになります。

サーバーレスではないワークロードをリフト & シフトでサーバーレスに移行しても、サーバーレスのすべてのメリットがすぐに得られるわけではないかもしれませんが、開発チームは、サーバーレステクノロジーが提供するものから恩恵を受ける可能性のあるアプリケーションの部分を、ストラングラーパターンを使用してリファクタリングできます。

Web アプリケーションをサーバーレスに移行する理由

サーバーレス環境でホストされる Web アプリケーションは、サーバーレスアプリケーションの自動スケーリング機能と、使用した分だけ支払いができることから最も恩恵を受けます。

トラフィックの少ない個人用Web アプリケーションがあると想像してみてください。サーバーレス環境でホスティングしている場合、サーバーを稼働させるために固定料金を支払う必要はありません。Web アプリケーションのリクエストはわずかで、残りの時間はアイドル状態です。

この利点は反対のケースにも当てはまります。サーバー上で運営されている小規模なeコマースサイトの所有者にとって、何百万人ものフォロワーを持つソーシャルメディアのインフルエンサーが自社製品の1つを推奨していると想像してみてください。突然、何千ものリクエストが届き、サイトが利用できなくなります。サイトがサーバーレスプラットフォームでホストされている場合、アプリケーションは受信するトラフィックに合わせてスケーリングされます。

移行の要件

移行を開始する前に、新しいアプリケーションに必要な非機能要件を定義することが重要です。これらの要件は、移行プロセス中にアーキテクチャ上の決定を行う必要がある場合に役立ちます。

この移行の非機能要件は次のとおりです。

  • ゼロから自動的にスケールアップ / ダウンする環境
  • アイドル時間の支払いはできるだけ少なくする
  • インフラストラクチャは可能な限り小さく構成する
  • アプリケーションの自動高可用性
  • 既存のコードへの最小限の変更

アプリケーション概要

このブログ記事では、MERN アプリケーションを移行する方法について説明します。元のアプリケーションは 2 つの異なるサーバーでホストされています。1 つには MongoDBが含まれ、もう 1 つには Node.js/Express と React アプリケーションが含まれます。

eコマースサイトのデモアプリケーションを構築します。データベースレイヤーには、製品、ユーザー、購入履歴が格納されます。サーバー層は、eコマースのビジネスロジック、製品画像のホスティング、ユーザーの認証と認可を処理します。Web レイヤーはすべてのユーザー操作を処理し、REST API を使用してサーバーレイヤーと通信します。

サーバーレス環境に移行するには、次の変更を行う必要があります。

  • データベースの移行: データベースをオンプレミスから MongoDB Atlas へ移行
  • バックエンドの移行: Node.js/Express アプリケーションをオンプレミスから AWS Lambda 関数へ移行
  • Web アプリケーションの移行: React Web アプリケーションをオンプレミスから AWS Amplify へ移行
  • 認証の移行: Amazon Cognito を使用するようにカスタムビルド認証を移行
  • ストレージの移行: Amazon S3Amazon CloudFront を使用するように、画像のローカルストレージを移行

以下の図は、移行するアプリケーションに対して提案されたソリューションを示しています。

提案されたアーキテクチャ

データベースの移行

データベースは、このアプリケーションのすべてのデータを含む MongoDB のコンテナに既にあります。MongoDB はスタックのデータベースエンジンなので、サーバーレスに移行するための推奨ソリューションは MongoDB Atlas を使用することです。Atlasは、自動的にスケーリングするクラウド内のデータベースクラスターを提供しており、使用した分だけ料金を支払います。

はじめに、新しい Atlas クラスターを作成し、既存のデータベースからサーバーレスのデータベースにデータを移行します。データを移行するには、まずデータベースのすべてのコンテンツをダンプフォルダーにダンプしてから、クラウドに復元します。

mongodump --uri="mongodb://<localuser>:<localpassword>@localhost:27017"

mongorestore --uri="mongodb+srv://<user>:<password>@<clustername>.debkm.mongodb.net" .

これを実行すると、データはクラウドに保存されます。次のステップは、サーバーの設定文字列を新しいデータベースを指すように変更することです。実際の動作を確認するには、移行の手順を説明するこのビデオをご覧ください。

バックエンドの移行

サーバーレイヤーはサーバー上で実行される Node.js アプリケーションであるため、Node.js/Express バックエンドの移行は、サーバーレス環境への移行が最も難しいレイヤーです。

この移行の 1 つの選択肢は、AWS Fargate を使用することです。Fargate はサーバーレスのコンテナサービスで、自動的にスケーリングでき、従量課金制です。もう 1 つの選択肢は、AWS AppRunner を使用することです。これは、自動スケーリングが可能で、従量課金制のコンテナサービスです。ただし、これらのオプションはいずれもゼロまでスケールできないため、移行要件と一致しません。

この Node.js アプリケーションのリフト & シフト移行のもう一つの選択肢は、Lambda を AWS Lambda Web Adapterと一緒に使用することです。AWS Lambda Web Adapterは、Express、Flask、SpringBoot などの使い慣れたフレームワークを使用して Web アプリケーションを構築し、それを Lambda で実行できるようにするオープンソースプロジェクトです。このプロジェクトの詳細については、GitHub リポジトリをご覧ください。

Lambda Web Adapter

このプロジェクトを使用して、Node.js/Express アプリケーションを関数コードとする新しい Lambda 関数を作成できます。すべてのコードをリフト & シフトで関数に入れることができます。手順を追ったチュートリアルをご覧になりたい方は、こちらの動画をご覧ください。

const lambdaAdapterFunction = new Function(this,`${props.stage}-LambdaAdapterFunction`,
            {
                runtime: Runtime.NODEJS_16_X,
                code: Code.fromAsset('backend-app'),
                handler: 'run.sh',
                environment: {
                    AWS_LAMBDA_EXEC_WRAPPER: '/opt/bootstrap',
                    REGION: this.region,
                    ASYNC_INIT: 'true',
                },
                memorySize: 1024,
                layers: [layerLambdaAdapter],
                timeout: Duration.seconds(2),
                tracing: Tracing.ACTIVE,
            }
        );

次のステップは、サーバーアプリケーションの HTTP エンドポイントを作成することです。これには、Amazon API GatewayApplication Load Balancer、または Lambda 関数 URL を使用する 3 つのオプションがあります。すべてのオプションが Lambda Web Adapter と互換性があり、この問題を解決できます。

このデモでは、関数 URL を選択します。関数 URL は設定が簡単で、1 つの関数 URL がすべてのルートを Express サーバーに転送するためです。API Gateway と ALB はより多くの設定が必要で、別途コストがかかりますが、関数 URL のコストは Lambda 関数に含まれています。

Web アプリケーションの移行

移行する最後のレイヤーは React アプリケーションです。Web レイヤーを移行し、移行要件を順守する最善の方法は、AWS Amplify を使用してWeb レイヤーをホストすることです。AWS Amplify は、Web アプリケーションのホスティングやWeb アプリケーションの CI/CD プロセスの管理など、多くの機能を提供するフルマネージドサービスです。さまざまな AWS リソースに接続するためのクライアントライブラリやその他の多くの機能を提供します。

React アプリケーションの移行は、AWS アカウントで新しい Amplify アプリケーションを作成し、React アプリケーションを GitHub などのコードリポジトリにアップロードするのと同じくらい簡単です。この AWS Amplify アプリケーションは GitHub ブランチに接続されており、このブランチに新しいコミットがあると、AWS Amplify はコードを再デプロイします。

Amplify アプリケーションは、環境変数を使用して関数 URL エンドポイント (サーバー URL) などの設定パラメーターを受け取ります。

const amplifyApp = new App(this, `${props.stage}-AmplifyReactShopApp`, {
            sourceCodeProvider: new GitHubSourceCodeProvider({
                owner: config.frontend.owner,
                repository: config.frontend.repository_name,
                oauthToken: SecretValue.secretsManager('github-token'),
            }),
            environmentVariables: {
                REGION: this.region,
                SERVER_URL: props.serverURL,
            },
        });

Webレイヤーをサーバーレスにする方法をステップバイステップでご覧になりたい方は、こちらのビデオをご覧ください。

次のステップ

ただし、この移行したアプリケーションをテストすると、2 つの問題が見つかります。1つ目は、ユーザーセッションが固定されないことです。ログインするたびに、アプリケーションから予期せずログアウトされます。2つ目は、新しい製品を作成するときに、その製品の新しい画像をアップロードできないことです。

パート2 (原文) では、それぞれの問題を詳細に分析し、解決策を見つけます。これらの問題は、このソリューションにはステートレスで変化しない特徴があるために発生します。この記事の次のパートでは、これらの問題を解決する方法について説明します。また、ソリューションのコストとパフォーマンスを分析します。

まとめ

この記事では、コードをあまり変更せずに、サーバーレスでない Web アプリケーションをサーバーレス環境に移行できるかどうかを学びます。AWS Lambda Web Adapter や AWS Amplify など、このプロセスに役立つさまざまなツールを学びます。

移行を実際に見て、そのためのすべての手順を学びたい場合は、プレイリストにはチュートリアルがすべて含まれており、移行がどのように可能かを学ぶことができます。

その他のサーバーレス学習リソースについては、Serverless Land をご覧ください。

この記事の翻訳はソリューションアーキテクトの小森谷一生が担当しました。