前回はこのシリーズの趣旨と作るものの概要を書いた。今回は調査から構成の決定まで一気に書く。
前回の記事は👇
https://qiita.com/noobaimo/items/f272f79fc159b20f2d70
調査と絞り込み
調査はClaudeCode、絞り込みは私が担当。
探した先は2か所。AWS公式の導入事例ページと、freeeやZOZOみたいな企業の技術ブログです。前者はアーキテクチャ図と使用サービスがセットで整理されてて読みやすい。後者はIaCの実態や運用上の判断まで読めます。
AWS公式事例・Web/EC系・サーバーレス/SaaS系・データ分析基盤系の4カテゴリで計32件調べて、こんな基準で絞りました。
- 実在企業が構成図を公開していること
- Terraformで一通り実装できること
- 数時間の検証後にdestroyして$5以内に収まること
- インフラ寄りの構成であること
残ったのは3件。
| 記号 | 企業/構成 | 特徴 |
|---|---|---|
| A | JPX総研(カーボン・クレジット取引) | CloudFront+API GW+ECS Fargate+Aurora+Step Functions/EventBridge |
| B | freeeサイン(電子契約) | WAF+ALB+ECS Fargate+Aurora PostgreSQL(Terraform全管理) |
| C | ベースフード(EC・定期通販) | CloudFront+ALB+ECS Fargate+Aurora+SQS+ElastiCache |
freeeサインを選んだ経緯
Cは早めに外しました。ECS+AuroraのコアにElastiCacheとSQSが乗る分、学習コストが散る。SQSとElastiCacheは別テーマとして後でやればいい、と。
迷ったのはAとB。Aは日本取引所グループ傘下の金融取引システムで、2023年にAWS公式事例として公開されてます。CloudFront+API Gateway+ECS Fargate+Auroraに、Step FunctionsとEventBridgeのジョブ制御まで乗ってて、読み取れる情報量がとにかく多い。
それでもBにした理由が2つ。
ひとつは、TerraformによるIaC管理が明言されてること。freeeの技術ブログには「全リソースをTerraformで管理している」と書いてあります。本PJの核がTerraformで再現することなので、IaC前提で語られた事例を選ぶ意味は大きい。
もうひとつはシンプルに完結すること。Aを選んだら、Step FunctionsとEventBridgeのジョブ制御まで実装することになる。バッチ制御を発展課題に回すなら、Bで十分でした。
省いた範囲
Bを選んだあと、何を作って何を省くかを決めました。
CodeDeploy(Blue/Greenデプロイ)は使わない。 freeeサインの元ネタにはCodeDeployによるBlue/Greenデプロイが含まれてますが、今回はECSのローリングアップデートで代替します。ECRにイメージをプッシュした後、aws ecs update-service --force-new-deployment を実行するだけ。ALBのターゲットグループも1つで済みます。
CI/CDパイプラインは対象外。 GitHub Actionsやecspressoによるパイプラインは扱いません。スクリプトで手動デプロイできるので、動作確認には支障なし。
マルチリージョンも省く。 元の記事はリージョン移行の話を含んでますが、本PJは東京リージョン単体(ap-northeast-1)での再現です。
CloudFront 追加の判断
オリジナルのfreeeサイン構成は、WAFをALBに直アタッチするREGIONAL構成で、CloudFrontを含みません。今回はここを変えて、Route53 → CloudFront → ALBの経路にしました。WAFもREGIONALスコープからCLOUDFRONTスコープに切り替え。
理由は3点。
HTTPS終端のエッジ化。 ACM証明書をus-east-1に作ってCloudFrontにアタッチすると、ユーザーから見た接続は常にHTTPS(TLS 1.2+)になります。CloudFront→ALB間はHTTP:80で完結。ALBに証明書を持たせる必要がありません。
WAFのアタッチ位置。 CloudFrontにWAF(CLOUDFRONTスコープ)を付けると、リクエストがリージョンに入る前のエッジ段階で検査・ブロックが走ります。CLOUDFRONTスコープはus-east-1のAPIで作る制約があって、Terraformではprovider aliasが必要。ここはちょっとハマりました。
ALBへの直接アクセスの排除。 ALBセキュリティグループのインバウンドを、CloudFrontのマネージドプレフィックスリスト(com.amazonaws.global.cloudfront.origin-facing)だけに絞る。こうすると、ALBのDNS名を直接叩いても繋がらなくなります。
この変更に伴って、Route53のAレコード(CloudFrontへのAliasレコード)、us-east-1のACM証明書、CloudFrontアクセスログの保存先S3バケット(90日保持)も、オリジナルにはなかったリソースとして追加してます。
最終的な構成
Terraformファイル構成
8ファイル構成にしました。cdn.tfがCloudFront・WAF・ACM・Route53・S3をまとめて管理します。
| ファイル | 役割 | 定義するリソース |
|---|---|---|
providers.tf |
Terraform・プロバイダー設定 | aws provider(東京)、aws provider(us-east-1) |
variables.tf |
入力変数とローカル値 | variable、locals |
network.tf |
VPCとネットワーク基盤 | VPC、サブネット、IGW、NAT Gateway、ルートテーブル、セキュリティグループ |
database.tf |
Aurora PostgreSQL | RDSクラスター、RDSインスタンス、DBサブネットグループ、Secrets Manager |
loadbalancer.tf |
ALB(公開層) | ALB、ターゲットグループ、リスナー |
cdn.tf |
CDN・グローバル層 | WAF v2、ACM証明書、Route53レコード、CloudFrontディストリビューション、S3バケット |
ecs.tf |
コンテナ実行基盤 | ECRリポジトリ、IAMロール、ECSクラスター、タスク定義、ECSサービス、CloudWatchロググループ |
outputs.tf |
apply後の確認用出力 | output(サイトURL、CloudFrontドメイン、ALB DNS、ECR URL、S3バケット名、RDSエンドポイント) |
コスト見積り(数時間検証→destroyの想定)
| サービス | 単価 | 3時間の概算 |
|---|---|---|
| Aurora Serverless v2 | $0.06/ACU-h(最小0.5 ACU) | $0.09 |
| NAT Gateway × 2 | $0.062/h × 2 | $0.37 |
| ALB | $0.025/h | $0.08 |
| ECS Fargate(2タスク) | 約$0.01/h | $0.03 |
| WAF CLOUDFRONT Web ACL | $5/月 | $0.02 |
| Route53 ホストゾーン | $0.50/月 | 誤差 |
| CloudFront | 無料枠(1 TB/月・1000万req) | $0.00 |
| S3(アクセスログ) | 無料枠内 | $0.00 |
| ドメイン(.click など) | 年額 $3.00(一回限り) | $3.00 |
| 合計(概算) | ≒ $3.60 |
なんと、ドメイン代が大半を占める結果に。NAT Gatewayを1台に絞る(single_nat_gateway = true)なら、時間課金分をさらに$0.19削減できます。
次回
構築編に入ります。terraform applyして、ECRにイメージをプッシュして、HTTPSアクセスを確認して、Aurora接続を確認して、destroyするところまで。詰まったところも含めてそのまま書く予定です。
出典: freee Developers Hub「freeeサインのAWSリージョン移行」
https://developers.freee.co.jp/entry/aws-region-migration
