AWS API Gateway VPCリンクでプライベートコンテナにインターネットからアクセスする


初めに

API Gateway のプライベート統合を利用して、ECS によりプライベートサブネットにデプロイされたアプリケーションにアクセスする方法について紹介します。プライベート統合は VPC 内のリソースに VPC 外からアクセスするための機能です。

API Gateway のプライベートな統合により、VPC 内にある HTTP/HTTPS リソースを VPC 外のクライアントがアクセスできるように簡単に公開できます。プライベート VPC リソースへのアクセスを VPC 境界を超えて拡張するために、プライベート統合で API を作成できます。

プライベート統合を使用するために VPC リンクという機能を使います。

VPC リンクを使用すると、Application Load Balancer または Amazon ECS コンテナベースのアプリケーションなどの、HTTP API ルートを VPC 内のプライベートリソースに接続するプライベート統合を作成できます。

なお VPC リンクを使ったプライベート統合は、ALB のスキームに内部向けを選択しないとうまくいかないようです。最初、インターネット向けでやっていましたが、エラーレスポンスが返ってきました。

以下のチュートリアルの CloudFormation のテンプレートも内部向けになっていました。

Scheme: internal

手順

1. VPC リンクを作成

「HTTP API の VPC リンク」を選択し、アプリケーションをデプロイする VPC を選択します。

サブネットとセキュリティグループを選択し、「作成」をクリックします。

2. ALB を作成

スキームは「内部」を選択します。インターネット向け ALB を作成したところ、ブラウザに

{"message": "Service Unavailable"}

と表示され、503 エラーが発生しました。ALB のトラフィックを確認したところ、リクエストが ALB まで到達していませんでした。VPC リンクを使ったプライベート統合は、内部向けしか選択できないようです。

VPC と プライベートサブネットを選択します。

ターゲットグループを作成します。種類は IP を選択します。

3. API Gateway の HTTP API を作成

HTTP API の「構築」をクリックします。

API 名を入力し、「次へ」をクリックします。

「次へ」をクリックします。

「次へ」をクリックします。

「作成」をクリックします。

ルートを作成します。「Create」をクリックします。

パスには「/{proxy+}」と入力し、「作成」をクリックします。

プライベート統合を作成します。「統合をアタッチする」をクリックします。

「統合を作成してアタッチ」をクリックします。

統合タイプは「プライベートリソース」を選択します。

以下のように ALB とリスナーを選択します。

VPC リンクを選択し、「作成」をクリックします。

4. エンドポイントを作成

以下のエンドポイントを 4 つ作成します。インターフェース型はすべてプライベート DNS 名を有効化します。

5. Fargate でアプリケーションをデプロイ

サービスを作成します。VPC とプライベートサブネット、セキュリティグループを選択します。パブリック IP の自動割り当ては「DISABLED」を選択します。

ALB を選択します。後はデフォルトの設定で進めます。

デプロイが完了しタスクが RUNNING になったら、API の呼び出し URL をブラウザに貼り付けます。

インターネットからプライベートコンテナにアクセスできました。

注意

以下は検証していませんが、定期的にリクエストを送って防ぎたいです。

VPC リンク経由で 60 日間トラフィックが送信されない場合は、INACTIVE になります。VPC リンクが INACTIVE 状態の場合、API Gateway は VPC リンクのネットワークインターフェイスをすべて削除します。これにより、VPC リンクに依存する API リクエストが失敗します。API リクエストが再開すると、API Gateway はネットワークインターフェイスを再プロビジョニングします。ネットワークインターフェイスを作成し、VPC リンクを再度アクティブ化するには、数分かかることがあります。VPC リンクステータスを使用して、VPC リンクの状態を監視できます。

ALB のスキーム

インターネット向けと内部向けの違いについて簡単にまとめます。

インターネット向け

  • インターネット向けロードバランサーのノードにはパブリック IP アドレスが必要
  • インターネット向けロードバランサーの DNS 名は、ノードのパブリック IP アドレスにパブリックに解決可能
  • インターネット向けロードバランサーは、クライアントからインターネット経由でリクエストをルーティングする

内部向け

  • 内部ロードバランサーのノードはプライベート IP アドレスのみを持つ
  • 内部ロードバランサーの DNS 名は、ノードのプライベート IP アドレスにパブリックに解決可能
  • 内部向けロードバランサーは、ロードバランサー用に VPC へのアクセス権を持つクライアントからのみ、リクエストをルーティングする

共通点

  • インターネット向けロードバランサーと内部向けロードバランサーは、どちらもプライベート IP アドレスを使用してリクエストをターゲットにルーティングする

確かにパブリックサブネットでコンテナを起動したとき、ノードの IP アドレスがプライベート IP だったのが不思議でした。

参考記事