Amazon Web Services ブログ
詳解: AWS App Runner プライベートサービス
この記事は Deep Dive on AWS App Runner Private Services (記事公開日: 2022 年 11 月 1 日) を翻訳したものです。
AWS App Runner は、Web アプリケーションと API サーバーを実行するためのフルマネージドサービスです。App Runner は、お客様のアカウントのインフラストラクチャをほとんどまたはまったく使用せず、安全な Web アプリケーションを構築して実行する体験をシンプルにします。ソースコードまたはコンテナイメージを提供すると、App Runner がアプリケーションコンテナをビルドしてデプロイし、裏側では自動的にスケーリングを行い、リクエストを負荷分散します。デプロイされると、App Runner サービスは、クライアントが HTTPS リクエストを送信できるサービス URL を取得します。
本日、App Runner はプライベートサービスのサポートを発表しました。これにより、Amazon Virtual Private Cloud (VPC) 内から App Runner サービスへのプライベートアクセスが可能になりました。デフォルトでは、App Runner サービスのエンドポイントはインターネット経由でアクセスできます。このアップデートにより、VPC からのみサービス URL にアクセス可能とする App Runner サービスのプライベートエンドポイントを選択できるようになりました。この機能は、AWS PrivateLink インターフェイス VPC エンドポイントによって提供されます。このブログ記事では、App Runner のネットワーク構成の概要と、受信トラフィックが VPC から App Runner サービスに、どのようにプライベートで流れるのかの詳細について説明します。また、デモアプリケーションを使用して、その機能をデモンストレーションします。
App Runner ネットワーキングの概要
App Runner が最初に発表されたときには、受信トラフィックのためのパブリックエンドポイントと、送信トラフィックのためのパブリックネットワーキングモードが提供されました。App Runner サービスへの受信トラフィックはパブリックインターネットからのみ許可され、送信トラフィック側では、アプリケーションはパブリックエンドポイントにのみ接続することができました (図 1) 。
今年の初めには、App Runner の VPC サポート (訳注: 日本語訳記事) の一般提供を発表しました。これにより、お客様のサービスの送信トラフィックにおいて、Amazon Virtual Private Cloud (Amazon VPC) でホストされているデータベースなどのプライベートリソースと通信できるようになりました (図 2) 。
本日の発表では、お客様の VPC 内のプライベートエンドポイントを使用して App Runner のサービスにアクセスできるようにする追加機能が提供されます。これにより、他のすべての App Runner の機能を使用しながら、サービスを VPC 内の他のサービスやリソースに安全に公開することができます (図 3) 。
この新機能を使用して、以前にリリースされた App Runner の VPC サポート機能 (図 2) と合わせて、アプリケーションへの受信トラフィックとアプリケーションからの送信トラフィックの両方をプライベートかつ安全に保つアーキテクチャを構築できます (図 4) 。
プライベートサービスのトラフィックのルーティング
App Runner のプライベートサービス機能は、お客様の VPC から App Runner サービスへのプライベート接続を提供する AWS PrivateLink インターフェイスエンドポイントによって提供されます。プライベート App Runner サービスでは、サービス URL は VPC インターフェイスエンドポイントのプライベート IP アドレスに解決されます。VPC 内では、トラフィックは VPC インターフェイスエンドポイントから App Runner サービスに流れ、パブリックインターネット経由でアクセスすることはできません。
VPC インターフェースエンドポイントを作成するには、サブネットとセキュリティグループを設定する必要があります。設定された各サブネット内に、App Runner サービスにトラフィックが流れる Elastic Network Interface (ENI) がプロビジョニングされるため、インターネットゲートウェイや NAT ゲートウェイは不要です。VPC インターフェースエンドポイントのサブネット構成によって、プライベート App Runner サービスへのプライベート接続の可用性を制御できます。VPC 内の複数のアベイラビリティーゾーン (AZ) にまたがる少なくとも 2 つのサブネットを提供することをお勧めします。VPC インターフェイスのエンドポイントにアタッチされたセキュリティグループは、VPC 内のどのサービスまたはリソースが App Runner サービスにアクセスできるかを制御します。エンドポイントの詳細については、Interface VPC Endpoints を参照してください。以下は、VPC インターフェイスエンドポイントを経由して、VPC から App Runner サービスにリクエストがどのように流れるかを表した図です (図 5) 。
複数の App Runner サービスを、同じ VPC インターフェースエンドポイントを使用して、VPC からプライベートアクセスするように設定できます (図 6) 。
リーダーボードアプリケーションのサンプル
ゲームのリーダーボードは、プレーヤーがお互いのパフォーマンスを評価することを可能にします。リーダーボードは、プレイヤーが最新のランキングを表示するために常にチェックする、一般的に読み取り負荷の高いアプリケーションです。アプリケーションの UI 部分と、ランキング計算を行うバックエンド部分を分離します。このブログ記事では、App Runner でホストされる 2 つのマイクロサービスを使用して、ゲームリーダーボードアプリケーションを構築します。
1 つめのマイクロサービスは、パブリックエンドポイントを持つフロントエンドの UI アプリケーションで、2 つめのマイクロサービスは、プライベートエンドポイントを持つバックエンドアプリケーションです。フロントエンドアプリケーションは、バックエンドアプリケーションと通信して、リーダーボードのデータを取得し、それをユーザーに表示します。図 2 で示したようなネットワーク構成になります。バックエンドアプリケーションは、VPC 内の Amazon ElastiCache Redis クラスターと通信してリーダーボードのデータを取得します。図 4 で示したようなネットワーク構成になります。サンプルアプリケーションがセットアップするネットワークアーキテクチャは次の通りです (図 7) 。
- 受信トラフィックは、パブリックフロントエンドサービスに入ります。
- フロントエンドサービスは、お客様の VPC へのプライベート接続を介して通信します。
- バックエンドサービスは、お客様の VPC からトラフィックを受信するように設定されます。
- バックエンドサービスは、VPC 内の ElastiCache Redis クラスターからデータを取得します。
- ElastiCache Redis クラスターは、バックエンドサービスにデータを返します。
- バックエンドサービスは、フロントエンドサービスにレスポンスを返します。
- フロントエンドサービスは、ユーザーにレスポンスを返します。
前提条件
- App Runner を利用可能な任意のリージョンにある VPC (アカウント内の既存の VPC を使用することもできます) 。このブログ記事では、バージニア北部 (us-east-1) リージョンを使用します。
ElastiCache Redis クラスターのセットアップ
1. ElastiCache Redis クラスターを設定するには、ElastiCache コンソールに移動し、Create Redis Cluster を選択します。クラスターの名前を入力し、ポートを 9000 に設定し、その他の設定はデフォルトのまま、Subnet group settings に進みます。
2. Subnet group settings セクションで、Create a new subnet group を選択し、VPC とその VPC 内のサブネットを選択します。高可用性のために、異なるアベイラビリティゾーンから少なくとも 2 つのサブネットを選択してください。
3. コンソールではすべてをデフォルトのままにし、Advanced settings で暗号化を有効にし、セキュリティグループを選択します。VPC のデフォルトセキュリティグループを選択します。他のすべての設定をデフォルトのままにして、ElastiCache Redis クラスターを作成します。
4. 以下のスクリーンショットは ElastiCache Redis クラスターの設定を示しています。後のステップで使用するため、Primary endpoint をメモしておきます。
5. バックエンドアプリケーションのために、ElastiCache Redis クラスターにデータを投入しましょう。こちらの手順に従って、ElastiCache Redis クラスターと同じ VPC 内の EC2 インスタンスに Redis CLI をセットアップしてください。EC2 インスタンスから Redis クラスターに接続し、Redis CLI を使用して以下のコマンドを実行して、リーダーボードゲームをプレイしているプレイヤーの名前と ID のデータを入力します。
バックエンドアプリケーションのセットアップ
次に、VPC 内の ElastiCache Redis クラスターとプライベートに通信するバックエンドアプリケーションを App Runner 上にセットアップします。新しくリリースされたプライベートサービス機能を使用し、バックエンドサービスのプライベートエンドポイントを用意します。このプライベートエンドポイントは、フロントエンドサービスがバックエンドサービスにアクセスするために使用されます。
このアプリケーションのソースコードは、ここからアクセスできます。server.py は、ElastiCache Redis クラスターからプレーヤーの ID を取得し、スコアを生成し、そのデータをレスポンスの一部として返すパス /getdata
を公開します。
1. Repository type を Source code repository として、サービスを設定します。ソースコードにアクセスするために GitHub 接続を使用し、このサービスの Repository と Branch を選択します。既存の接続がない場合は、App Runner コンソールの Add new フローから、新しい GitHub 接続を作成します。
2. Runtime に Python 3、Build command に pip install -r requirements.txt
、Start command に gunicorn server:app --log-level=debug
、サービスの Port に 8000 を選択します。
3. サービスに leaderboard-backend-service
という名前を付け、環境変数として REDIS_URL を追加します。REDIS_URL には、このサービスが通信に使用する ElastiCache Redis クラスターのプライマリエンドポイントを格納します (訳注: “:9000” は不要です) 。この URL は、「ElastiCache Redis クラスターのセットアップ」セクションのステップ 4 で ElastiCache Redis クラスターの Primary endpoint から取得できます。
4. 以降のセクションはデフォルトのままにして、Networking セクションに移動します。Private endpoint を選択し、新しい VPC インターフェイスエンドポイントを作成します。フロントエンドサービスがバックエンドサービスとプライベートに通信するのに必要な VPC インターフェースエンドポイントを作成する VPC と、そのサブネット、セキュリティグループを選択します。既存の VPC インターフェイスエンドポイントがある場合は、それを使用することもできます。
5. VPC 内の ElastiCache Redis クラスターにプライベートで通信するように送信トラフィックを設定します。Custom VPC オプションを選択し、新しい VPC コネクタを追加します。このコネクタの VPC、サブネット、セキュリティグループを設定します。これは、ElastiCache Redis クラスターをデプロイしたのと同じ VPC です。シンプルにするために、すべての設定で同じサブネットとセキュリティグループを使用します。
6. 以降のセクションはデフォルトのままとして、設定内容をレビューし、Create & deploy を選択してバックエンドサービスを作成します。以下のスクリーンショットは、バックエンドサービスの設定の概要を示しています。フロントエンドアプリケーションのセットアップで使用するため、Default domain のサービス URL をメモします。
フロントエンドアプリケーションのセットアップ
この時点までに、プレイヤー ID と名前が格納された ElastiCache Redis クラスターをデプロイしました。また、ElastiCache Redis クラスターからリーダーボードのデータをプライベートに取得し、VPC にプライベートエンドポイントを持つバックエンドサービスをデプロイしました。
それでは、リーダーボードのデータをブラウザに表示するフロントエンドアプリケーションをセットアップしましょう。フロントエンドアプリケーションは、バックエンドサービスにリクエストし、レスポンスの一部としてリーダーボードデータを取得します。フロントエンドサービスはパブリックエンドポイントを持ち、VPC コネクタを介してバックエンドサービスと通信し、VPC 内のバックエンドサービスのプライベートエンドポイントにリクエストを送信します。このアプリケーションのソースコードには、ここからアクセスできます。
1. フロントエンドサービスのセットアップは、バックエンドサービスのセットアップと似ていますが、いくつかの違いがあります。
同じ GitHub 接続 (「バックエンド アプリケーションのセットアップ」セクションのステップ 1) を使用して、バックエンドアプリケーションのリポジトリ、およびブランチの値でサービスを設定します。また、同じ Runtime、Build command、Start command、および Port を選択します。バックエンドサービスのサービス URL を保持する BACKEND_URL 環境変数を設定します (訳注: “https://” は不要です) 。サービス URL は、「バックエンドサービスのセットアップ」のステップ 6 で取得することができます。
2. Networking 設定では、受信トラフィック用に Public endpoint を選択し、送信トラフィック用に VPC コネクタを持つ Custom VPC を選択します。これは、バックエンドサービスがプライベートエンドポイントを持つのと同じ VPC です。
3. コンソールのステップを続行し、Create & deploy を選択してフロントエンドサービスを作成します。
おめでとうございます! Service overview の Default domain からフロントエンドサービスの URL を取得し、ブラウザで開くと以下のスクリーンショットのように表示されます。
4. Refresh Scores ボタンをクリックすると、バックエンドサービスへのリクエストが行われ、ブラウザ上にリーダーボードのデータが表示されます。
5. フロントエンドとバックエンドのサービスのアプリケーションログから、確かに通信が行われていることを検証してみましょう。サービスのアプリケーションログを見つけるには、サービスの Logs タブで、Application logs を選択します。
フロントエンドサービスとバックエンドサービスのアプリケーションログに、以下のような出力があり、フロントエンドサービスからバックエンドサービスへリクエストがどのように送信されるかを示しています。
トラブルシューティング
セキュリティグループによって保護されている通信経路が複数あります。これらの経路での通信がセキュリティグループによって許可されていることを確認してください。フロントエンドとバックエンドサービス間の通信では、VPC の VPC インターフェースエンドポイントのセキュリティグループが、フロントエンドサービスに関連する VPC コネクタのセキュリティグループからのアクセスを許可している必要があります。同様に、バックエンドサービスと ElastiCache Redis クラスター間の通信では、VPC の ElastiCache Redis クラスターのセキュリティグループは、バックエンドサービスに関連する VPC コネクタのセキュリティグループからのアクセスを許可している必要があります。このデモでは、すべてのサービスとリソースに VPC のデフォルトセキュリティグループを使用しており、自分自身からの通信を許可しているため、必要なすべての経路で通信が可能になっています。
後片付け
このブログ記事で作成したリソースを削除するには、以下の手順を実行してください。
1. フロントエンドとバックエンドの両方の App Runner サービスを削除します。
2. バックエンドサービスのプライベートエンドポイントを設定するために使用した VPC インターフェースエンドポイントを削除します。これは、App Runner コンソールの Networking Configuration ビューで実行できます。Incoming Traffic の下にある VPC インターフェースエンドポイントに移動し、削除します。これは、上記のサービスが正常に削除された後に実行できます。
3. ElastiCache Redis クラスターと、Redis CLI をセットアップした EC2 インスタンスを削除します。
4. このブログ記事の一部として GitHub 接続をセットアップした場合、App Runner コンソールからその接続も削除します。また、接続のセットアップ中に承認された GitHub アカウントの GitHub アプリケーションを削除します。これは GitHub アカウントの Settings から実行できます。
利点
この機能により、より大きなマイクロサービスアーキテクチャの一部であり、他のマイクロサービスからプライベートにアクセスする必要がある中間層やバックエンドの内部アプリケーションを構築できます。また、スタンドアローンの企業内ウェブサイトやインターネットに接続しないアプリケーションを安全に構築することができます。開発中のアプリケーションを非公開でアクセスできるようにすることもできます。また、PrivateLink との統合を利用して、App Runner サービスの前に API Gateway や AWS Load Balancer を構成できるため、App Runner サービスを既存のアーキテクチャ全体の一部として構成することが可能です。このユースケースについては、別のブログ記事で取り上げる予定です。
まとめ
このブログ記事では、プライベートサービス機能の発表に伴い、現在 App Runner で利用可能なさまざまなネットワーク構成について説明しました。App Runner は、App Runner サービスへの受信トラフィックについて、パブリックエンドポイントモードとプライベートエンドポイントモードをサポートするようになりました。プライベートエンドポイントモードでは、受信トラフィックを VPC に制限し、サービスをプライベートかつ安全にすることできます。ユースケースに応じて、特定の送信トラフィックモード (パブリックまたはカスタム VPC) と、特定の受信トラフィックモードを組み合わせて選択することができます。また、マイクロサービスアーキテクチャでリーダーボードアプリケーションのサンプルを構築し、パブリック App Runner サービス、プライベート App Runner サービス、ElastiCache Redis クラスター間のプライベート通信を可能にしました。プライベートサービス機能は、最も要望の多かった機能の 1 つであり、これをお客様に提供できることを嬉しく思います。GitHub の App Runner ロードマップへのフィードバックをお待ちしています。
翻訳はプロフェッショナルサービスの杉田が担当しました。原文はこちらです。