学習のために構築した環境を紹介します。
S3やECSなどの主要リソースに加え、Terraformに触れたことがある方向けの内容です。
本記事は「①設計・構成解説編」と「②実装詳細編」の2章構成です。
本章では、全体の構成と技術選定のポイントについて解説します。
②実装詳細編はこちらです。
コード全体は以下から確認ください。
1. 実装要件
下記を実装し動作させることが今回の学習目的です。
- 静的フロントエンド: S3 + CloudFront
- 動的バックエンド: ALB + ECS Fargate
- 認証・認可: Amazon Cognito による「ALB認証」の導入
- セキュリティ: AWS WAFによる保護、ACMによるHTTPS化、S3のOAC
- 管理: TerraformによるIaC
2. 本構成のメリット
- Cognito による認証
- アプリケーションコードに認証ロジックを書くことなく、インフラレベル(ALB)で正規ユーザー以外のアクセスを遮断
- コンテナ基盤(ECS Fargate)の採用
- サーバーのパッチ当て等の運用負荷を抑えつつ、複雑なビジネスロジックや長時間実行が必要な処理にも対応可能な拡張性を確保
- CloudFront によるエッジ保護とドメイン統合
- S3(フロント)とALB(バック)のドメインをCloudFrontで統合し、CORS問題を根本から回避
3. 設計思想と技術選定のポイント
3-1. 多層防御によるセキュリティ設計
- Cognitoによる「直叩き」防止
APIエンドポイントのURLが漏洩しても、Cognito認証を通過していないリクエストはALBで拒否されます。これにより、バックエンドのリソースを保護しています。 - S3の完全非公開化(OAC)
Origin Access Control (OAC) を使用し、CloudFrontからの署名付きリクエストのみ許可し、S3バケットへの直接アクセスを遮断しています。 - WAFの二重配置
エッジ(CloudFront)とリージョン(ALB)の両方にAWS WAFを配置し、一般的なWeb攻撃からインフラを多層的に守ります。
3-2. ネットワーク設計
- パブリック/プライベート分離
ECSタスクはプライベートサブネットに配置し、外部との通信はNATゲートウェイ経由に限定。ALB、NATゲートウェイのみをパブリックに配置し、接点を最小化しています。 - Route 53 Aliasレコードの活用
Zone Apex(ドメイン名そのもの)でCloudFrontを利用可能にするため、CNAMEではなくRoute 53のAlias機能を利用しています。これにより、ドメイン名を直接CloudFrontのディストリビューションに関連付けています。
3-3. 柔軟なキャッシュ・ルーティング戦略
- パスベースの挙動制御
- /index.html: 静的コンテンツとしてエッジでキャッシュ
- /api/*: バックエンド(ALB)へ転送。キャッシュは無効化し、常に最新の動的データを返却
- /api/public/*: 認証不要のエンドポイントとして、特定のパスのみCognito認証をスキップするルールをALBに定義
4. 構築時の注意点
Terraformで構築する際、エラーになりやすい・反映されにくいポイントです。
- CloudFront用のACMは必ず us-east-1
メインリージョンが東京(ap-northeast-1)でも、CloudFrontに紐付ける証明書はバージニア北部で作成しなければなりません。Terraformでは provider の使い分けが必須です。 - CognitoのコールバックURL設定
ALBを使って認証する場合、AWSの仕様で /oauth2/idpresponse というパスが認証データの受け取り場所として予約されています。
Cognitoは、あらかじめ「許可リスト(Callback URLs)」に登録されたURL以外には、認証情報を送信しない仕組みになっています。
リストにこのパスがないと、Cognitoは不正アクセス防止のためにエラーを返します。 - ECSのセキュリティグループ連携
ECSタスクのSGは、ALBのSGからのインバウンドのみを許可。これにより、意図しない経路からのアクセスを防止します。 - 証明書のDNS検証待ち
aws_acm_certificate_validation リソースを使用し、証明書の検証が完了してからCloudFrontやALBを作成するように依存関係を制御します。
具体的なTerraformコードの実装については、第2章で解説します。
5. 参照
CloudFrontドキュメント
S3ドキュメント
ECSドキュメント
ELBドキュメント
Terraformドキュメント
