以前紹介したECSアーキテクチャの一部変更し、セキュリティを重視した環境を紹介します。以前の環境はこちらを参照ください。
本記事はS3やECSなどの主要リソースに加え、Terraformに触れたことがある方向けの内容です。
コードは以下のリンクから確認ください。
1. 実装要件
今回の構築目的は、NLBをプライベートサブネットに配置し、外部からの直接アクセスを物理的に遮断し、API GatewayのVPC Linkを使用して、閉域網経由でリクエストを転送することで、セキュリティを強化することです。
- 静的フロントエンド: S3 + CloudFront
- 動的バックエンド: API Gateway + NLB + ECS Fargate (VPC Link接続)
- ネットワーク: NLBをプライベートサブネットに配置
- ドメイン統合: CloudFrontでS3とAPI Gatewayを同一ドメイン配下に集約
- セキュリティ: APIキー認証(CloudFront付与)、AWS WAF
- 管理: TerraformによるIaC
2. 本構成のメリット
ALB + Cognito構成からAPI Gateway + NLBに変更することで以下のメリットがあります。
- バックエンドの完全隠蔽(VPC Link)
NLBをInternal(内部)配置し、API GatewayからVPC Link経由で接続。バックエンドへのパブリックな経路を完全に遮断しました。 - API管理機能の強化
APIキーによる簡易的なアクセス制御や、使用プラン(Usage Plan)によるスロットリング(流量制限)をインフラレベルで提供します。
3. 設計思想と技術選定のポイント
3-1. CloudFrontによるドメイン統合
S3へのリクエストと、/prod/data/* へのリクエストをCloudFrontの behaviors で切り分けます。これにより、フロントエンドJavaScriptから相対パスでAPIを叩けるようになり、環境ごとのドメイン管理やCORS対応の工数を削減しています。
3-2. CloudFrontからのAPIキー付与(多層防御)
API GatewayでAPIキー認証を有効にしつつ、そのキーをCloudFrontの「カスタムオリジンヘッダー」に設定します。これにより、ユーザー(クライアント)にAPIキーを教える必要がなく、CloudFrontを経由しないAPIへの直接アクセスを確実に拒否できます。
3-3. ネットワーク設計
今回の構成はバックエンドへのパブリックな経路を完全に遮断し、セキュアな環境を作ることがコンセプトです。
そのため、CloudFront→API Gateway→VPC Link→NLB→ECSという経路になっています。
NLBを使う理由
REST APIを使用するAPI Gatewayでは、ALB とのプライベート統合はサポートされていません。そのため、REST APIによるAPI Gatewayを利用しつつ、API GatewayとECSタスク間をプライベートな経路に保つためには、NLBを経由させる必要があります。
RestAPIを使う理由
下記2つの理由からRestAPIを使います。
-
API GatewayのAPIキー認証はREST APIのみが対応しており、HTTP APIでは対応していません。
-
HTTP APIを使用するAPI Gatewayパターンでは、仕様上WAFとの連携ができません。
API GatewayをNLBの手前に配置する理由
VPC Link:
API Gatewayには「VPC Link」という機能があり、これを利用することで、インターネットを経由せずにAPI GatewayからVPC内部のNLBへ直接リクエストを飛ばせます。
認証・認可の集約:
APIキー認証や、WAF、スロットリング(流量制限)をAPI Gatewayに持たせることで、バックエンド(NLB/ECS)に到達する前に不正なリクエストをフィルタリングできます。
フルマネージド:
高可用性が担保されており、運用の手間がかかりません。
4. 構築時の注意点
Terraformでこの構成を組む際、特につまずきやすいポイントです。
- API Gatewayの再デプロイ制御
API Gatewayのリソース(MethodやIntegration)を変更しても、deployment リソースが自動で更新されないことがあります。
トリガーを設定し、設定変更時に確実に「新しいデプロイメント」が作成されるように制御します。 - API GatewayのステージパスとCloudFrontのパス
API Gateway側で prod などのステージ名が付与される場合、CloudFrontの path_pattern と origin_path の組み合わせに注意が必要です。パスの不一致で 404 エラーが出るケースが多いため、設計段階でパス構造を明確にしておきます。
5. 参照
CloudFrontドキュメント
S3ドキュメント
ECSドキュメント
NLBドキュメント
ECS構成参考ドキュメント
Terraformドキュメント
