初めに
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 だったのが不思議でした。
参考記事