全体像: タスク管理 SaaS「Tasuku」の要件とアーキテクチャ
インフラの設計判断は、載せるものの要件が決まって初めて語れます。サブネットの数もデータベースの冗長化も権限の渡し方も、突き詰めれば「何をどの規模でどれだけ止めずに動かしたいか」への答えだからです。そこで本連載は、章をまたいで使い続ける題材をひとつ定義するところから始めます。
この章では、題材となるタスク管理 SaaS「Tasuku」の要件を確定し、それを AWS の 7 サービスにどう割り当てるかを一枚の図にします。あわせて、第 2 章以降の構築順序がなぜこの並びなのかを、リソース間の依存関係から説明します。この章にコードは登場しません。
1.1. 題材: タスク管理 SaaS「Tasuku」
Tasuku は、チームでタスクを管理する架空の SaaS です。機能は次の 4 つに絞ります。
| # | 機能 | インフラに効いてくる点 |
|---|---|---|
| 1 | メールアドレスとパスワードによるユーザー登録とログイン | セッションと認証情報を扱うため、通信は全区間 HTTPS にする |
| 2 | プロジェクトとタスクの作成、編集、削除 (担当者、期限、状態) | リレーショナルデータベースが要る。テナント分離は DB の行レベルで行う |
| 3 | タスクへのファイル添付 | 画像や PDF のような非構造データの置き場が要る。DB には向かない |
| 4 | チームへのメンバー招待と権限管理 | アプリケーション側の関心。インフラには追加要求なし |
機能を 4 つに絞るのは、この連載の主題がアプリケーションではなくインフラだからです。それでも、この 4 つで「Web アプリと API」「リレーショナルデータベース」「オブジェクトストレージ」という本番 Web サービスの典型要素が出そろいます。
メール通知、全文検索、CDN による配信高速化は扱いません。いずれも実サービスなら検討する機能ですが、追加するサービス (SES、OpenSearch、CloudFront) が主役 7 サービスの理解に必須ではないため、連載のスコープ外とします。
1.2. 非機能要件と規模の想定
機能の一覧だけでは、まだインフラの形は決まりません。同じタスク管理でも、社内 10 人で使うものと数万人が使うものでは設計が変わります。Tasuku では次を前提にします。
- 規模: 数十テナント、同時アクセス数百ユーザー程度。個人開発や小規模 SaaS の立ち上げ期を想定します
- リージョン: 東京リージョン (ap-northeast-1) 単一。利用者は国内想定です
- 可用性: 2 つのアベイラビリティゾーン (AZ) に分散し、1 つの AZ が落ちてもサービスを継続できる形にします
- セキュリティ: インターネットに公開するのは HTTPS の入口だけとし、アプリケーションとデータベースは外から直接届かない場所に置きます。データベースのパスワードのような秘密情報は、コードや設定ファイルに直接書きません
- データ保護: データベースは日次バックアップを取り、誤操作時に特定時点へ復元できるようにします
この規模想定は、以降の章でインスタンスサイズや冗長化の判断に迷ったときの基準になります。「数百万ユーザーならこうするが、Tasuku の規模ならこちらで足りる」という形で、判断のたびに立ち返ります。
1.3. アプリケーションとインフラの境界
本連載では、アプリケーションのコードを 1 行も書きません。Tasuku のアプリは「すでに完成していて、コンテナイメージとして渡される」前提を置きます。具体的には次の 2 つのイメージが存在するとみなします。
- web: ブラウザ向けの画面を返すコンテナ。ポート 3000 で待ち受ける
- api: JSON を返す REST API のコンテナ。ポート 8080 で待ち受ける
アプリに対する仮定は「HTTP で待ち受けること」と「GET /healthz に 200 を返す口があること」だけです。ヘルスチェック用の口を仮定するのは、後の章で ALB が「どのコンテナが正常か」を判断する材料に使うためです。イメージ名とポート番号は Terraform の変数にするので、読者が手元で試すときは nginx のような公開イメージに差し替えられます。
インフラの記事にアプリのコードが混ざると、読者は「この設定はアプリ固有か、それともどんなアプリでも要るのか」を切り分けながら読むことになります。アプリを完成品として扱えば、登場する設定はすべてインフラ側の関心だと確定します。
1.4. 全体アーキテクチャとリクエストの流れ
Tasuku の完成形は次のとおりです。
ユーザーがタスクに画像を添付する操作を例に、この図を一周します。
- ブラウザが
tasuku.exampleの IP アドレスを Route 53 に問い合わせ、ALB の所在を得ます - ブラウザは ALB へ HTTPS で接続します。TLS はここで終端します
- ALB はリクエストのホスト名を見て、
tasuku.exampleなら web、api.tasuku.exampleなら api のコンテナ群へ振り分けます。振り分け先は、ヘルスチェックに応答している正常なコンテナに限られます1 - api はタスクのメタデータ (タイトル、担当者、期限) を RDS の PostgreSQL に読み書きします
- 添付ファイルの実体は S3 に保存します。DB には S3 上の置き場所だけを記録します
点線で描いた ECR、CloudWatch Logs、Secrets Manager は、リクエストの経路には現れませんが、コンテナの起動と運用を裏で支えます。コンテナイメージは ECR から取得し、アプリのログは CloudWatch Logs へ送り、DB パスワードは Secrets Manager から起動時に注入します。
1.5. 7 つの主役サービスと 4 つの脇役
図に登場したサービスを、連載での扱いとあわせて整理します。まず主役の 7 つです。
| サービス | Tasuku での役割 | 登場章 |
|---|---|---|
| VPC | AWS 内に論理的に分離された仮想ネットワーク区画を作り2、サブネットで公開範囲を層に分ける | 第 4 章 |
| IAM | 「誰が、何に対して、どの操作をできるか」の認証と認可を定義する | 第 3 章 |
| S3 | 添付ファイルの保存に加え、ALB のアクセスログと Terraform の state ファイルの置き場も担う | 第 5 章 |
| ALB | OSI 参照モデルの第 7 層 (アプリケーション層) で動くロードバランサー3。HTTPS の終端と、ホスト名によるコンテナ群への振り分けを担う | 第 6 章 |
| Route 53 | tasuku.example の DNS を管理し、独自ドメインへのアクセスを ALB へ導く | 第 7 章 |
| ECS | コンテナの実行基盤。起動タイプに Fargate を使い、EC2 サーバーの管理なしでコンテナを動かす4 | 第 8 章と第 10 章 |
| RDS | PostgreSQL のマネージドサービス。自動バックアップと特定時点への復元を AWS 側の機能として提供する5 | 第 9 章 |
次に脇役の 4 つです。専用の章は設けず、必要になった章の中で設計と実装をあわせて扱います。
| サービス | 役割 | 扱う章 |
|---|---|---|
| ECR | コンテナイメージの置き場 (レジストリ) | 第 8 章 |
| ACM | TLS 証明書の発行と管理 | 第 7 章 |
| CloudWatch Logs | コンテナのログの集約先 | 第 8 章 |
| Secrets Manager | DB パスワードなど秘密情報の保管と注入 | 第 9 章と第 10 章 |
主役と脇役の線引きは、この連載が「設計判断を掘る対象」として扱うかどうかです。脇役側にも設計の選択肢はありますが、Tasuku では定番の使い方をそのまま採用し、選択肢の比較は主役 7 サービスに集中させます。
1.6. 構築の順序: なぜネットワークから始めるか
第 2 章以降は、次の順でリソースを積み上げます。
この並びは、AWS のリソースが持つ「作成時に指定する依存先」をたどった結果です。たとえば ALB も ECS も RDS も、作成時に「どのサブネットに置くか」の指定を要求します。置き場であるサブネットが先に存在しなければ、これらは作れません。VPC が早いのはそのためです。
一方で、依存関係だけでは決まらない配置もあります。本連載では次の 3 つを意図して選びました。
- IAM を第 3 章に置く: IAMロールが実際に要るのは ECS が登場する第 8 章からです。それでも先頭側に置くのは、ポリシー JSON の読み書きが以降の全章に登場し、読めないまま進むと各章の権限設定が呪文になるからです。第 3 章は「権限モデルの文法」に絞り、個別のロール作成は使う章で行います
- ALB を ECS より先に作る: 第 6 章の時点ではまだコンテナがいないため、ALB には固定のメンテナンス応答を返させて、HTTP でインターネットに公開するところまで進めます。第 7 章でこの入口を HTTPS 化し、第 10 章で応答先を本物のコンテナへ切り替えます
- ECS を前編と後編に分ける: ECS は 7 サービスの中でも関連リソースが多く、1 章に詰めると個々の設計判断が流れ作業になります。前編 (第 8 章) で単発のタスクを動かして基盤を確かめ、DB (第 9 章) をはさんで、後編 (第 10 章) で常駐サービスとして公開します
つまり、この連載のインフラは一度では完成形になりません。HTTP 公開から HTTPS 化へ、固定応答から本物のアプリへと段階的に育てていきます。実務でも、動く状態を保ったまま少しずつ変更を加える進め方のほうが、問題が起きたときに原因の範囲を絞れます。
1.7. 手元で試すための前提
連載のコードを手元で動かす場合の前提です。読むだけであれば不要です。
- AWS アカウント: 管理者相当の権限で操作できるアカウント。権限の絞り方自体は第 3 章で扱います
- Terraform: v1.13 系で検証しています。公式のインストール手順に従ってください
- AWS CLI: 認証情報の設定と、動作確認のコマンドに使います
- 独自ドメイン: 第 7 章以降で使います。第 6 章までは不要です。本文のドメインは予約済みの例示用 TLD である
tasuku.exampleを使うため、そのままでは登録できません。読者自身のドメインに読み替えられるよう、Terraform 側は変数にしてあります
この連載の構成を実際に作ると、時間課金のリソース (NAT Gateway、ALB、RDS など) の費用が発生します。どの章で何の課金が始まるかは各章の冒頭に明示します。第 2 章の最初の apply では、想定外の課金に早く気づくための予算アラートを作ります。
本章のまとめ
- 題材 Tasuku は「Web と API のコンテナ」「PostgreSQL」「ファイル添付」を持つ小規模 SaaS で、この構成だけで主役 7 サービスがすべて登場します
- アプリケーションは完成済みのコンテナイメージとして扱い、本連載の記述はインフラ側の関心に限定します
- 公開する入口は ALB の HTTPS だけに絞り、アプリと DB はプライベートサブネットに置きます
- 構築順序はリソースの依存関係で決まる部分 (VPC が先) と、学習と運用の判断で決めた部分 (IAM 先行、ALB の先行公開、ECS の 2 分割) があります
次に読む
- 第 2 章: Terraform 基礎: 最小の Terraform 構成を書き、最初の apply で予算アラートを作ります
- 連載の目次: 全 12 章の構成と読み進め方
- インフラ・運用ドメイン: この連載が属するドメインのトップページ