0. はじめに
AWS未経験のインフラエンジニアが、AIと一緒に要件定義からリリースまでをやってみた!
今回は、AWS上でWebシステム(CRUDアプリ)構築を行う実践記録です。
理解の深化が目的なので、GUIで構築したのちにteraformでも実装することにします。
インフラ構築を主としたいので、アプリケーションに関する定義については曖昧に済ませます。
本取り組みは、以下の全7回のシリーズとして展開します。インフラ構築の全体像を俯瞰する一助となれば幸いです。
| 第1回 | 要件定義編(本記事) |
|---|---|
| 第2回 | 基本設計編 |
| 第3回 | 詳細設計編 |
| 第4回 | 運用設計編 |
| 第5回 | 構築編①(マネジメントコンソールによる手動構築) |
| 第6回 | 構築編②(TerraformによるIaC構築) |
| 第7回 | テスト編 |
| 第8回 | リリース・まとめ編 |
では、要件定義書スタート!
1. はじめに
1.1 目的
本文書は、AWS上に構築する掲示板WebアプリケーションのAWSインフラに関する要件を定義するものである。
アプリケーション実装品質よりも AWSインフラの設計・構築・運用知識の習得 を主目的とし、実務で一般的に採用されるアーキテクチャパターンを意識した構成とする。
1.2 スコープ
対象範囲
- AWSインフラ基盤全体
- 掲示板機能を提供するWebアプリケーション
- Nginxによる静的・動的コンテンツ配信
- データストアはRDSを使用する
対象外
- メール配信機能
- 外部SNS連携
- 決済機能
- モバイルアプリ対応
1.3 用語定義
| 用語 | 定義 |
|---|---|
| ー | ー |
1.4 関連ドキュメント
| ドキュメント名 | 概要 | 作成予定回 |
|---|---|---|
| 基本設計書 | リージョン・AZ選定・各サービス採用理由 | 第2回 |
| 詳細設計書 | VPC/Subnet CIDR設計・SG設計・IAMポリシー定義 | 第3回 |
| 運用設計書 | 監視設計・障害対応フロー・バックアップ運用 | 第4回 |
| 構築手順書 | Teraformコード、GUI手順書 | 第5、6回 |
| テスト仕様書 | 機能テスト・負荷テスト・セキュリティテスト | 第7回 |
2. システム概要
2.1 概要
ユーザーが投稿・閲覧・編集・削除を行える掲示板機能を提供するWebアプリケーション。フロントエンドは静的HTMLとしてCloudFront経由で配信し、バックエンドはEC2(Nginx)上で稼働するWebアプリケーションがHTTPリクエストを処理する。データはRDS(MySQL)に永続化する。
2.2 システム構成概要
インターネット側からの通信はRoute 53でDNS解決され、CloudFrontでHTTPS終端・CDNキャッシュ・WAFフィルタリングが行われる。CloudFrontのオリジンとして配置されたALBがリクエストをプライベートサブネット上のEC2インスタンス群へ振り分ける。EC2はAuto Scaling Groupにより管理され、RDSに対してSecrets Manager経由で取得した認証情報を用いて接続する。全リソースのメトリクスおよびログはCloudWatchに集約し、閾値超過時にSNS経由でアラートを通知する。
Internet
│
▼
[Route 53] ─── DNS解決
│
▼
[CloudFront] ─── HTTPS終端 / CDNキャッシュ / WAF適用
│
▼
[ALB] ─── L7ロードバランシング(パブリックサブネット / マルチAZ)
│
┌─┴─┐
▼ ▼
[EC2] [EC2] ─── Nginx / Webアプリ(プライベートサブネット / マルチAZ)
└─┬─┘
│ Auto Scaling Group
▼
[RDS MySQL] ─── プライベートサブネット / マルチAZ
(Secrets Manager経由で接続情報取得)
[CloudWatch] ─── 全リソースの監視・ログ収集・アラート
[IAM] ─── EC2ロール・サービス間アクセス権限管理
2.3 使用AWSサービス一覧
| サービス | 用途 | 論理配置 |
|---|---|---|
| Route 53 | DNS管理・ヘルスチェック | グローバル |
| ACM | SSL/TLS証明書の発行・管理 | グローバル(CloudFront用) |
| CloudFront | HTTPS終端・CDN・WAFアタッチ | グローバル |
| WAF | Webアプリ攻撃防御 | CloudFrontに紐付け |
| ALB | ロードバランシング・ヘルスチェック | パブリックサブネット(マルチAZ) |
| EC2 | Webサーバー / アプリケーション実行 | プライベートサブネット(マルチAZ) |
| Auto Scaling | EC2の自動スケールアウト/イン | EC2 Auto Scaling Groupに紐付け |
| RDS | データベース | プライベートサブネット(マルチAZ) |
| Secrets Manager | シークレット管理 | VPCエンドポイント経由 |
| CloudWatch / Logs | メトリクス収集・ログ集約・アラーム | グローバル |
| SNS | CloudWatchアラームのメール通知 | グローバル |
| IAM | アクセス権限管理 | グローバル |
| VPC / Subnet / SG / NACL |
ネットワーク分離・通信経路制御 | リージョン内 |
| VPCエンドポイント | プライベートアクセス | VPC内 |
3. 機能要件
-
3.1:投稿作成機能
ログイン済みユーザーは、タイトル(最大100文字)および本文(最大10,000文字)を入力して新規投稿を作成できる。タイトル・本文はどちらも必須入力とし、空文字または空白のみの場合はバリデーションエラーをユーザーに通知する。作成日時・更新日時はサーバーサイドで自動付与する。正常作成後は一覧画面へリダイレクトする。
-
3.2:投稿一覧表示機能
未認証を含む全ユーザーは投稿一覧を閲覧できる。投稿は作成日時の降順で表示し、1ページあたり20件を上限としてページネーションを実装する。表示項目はタイトル・投稿者名・作成日時・更新日時とする。
-
3.3:投稿詳細表示機能
未認証を含む全ユーザーは、一覧から任意の投稿を選択して詳細ページを閲覧できる。表示項目はタイトル・本文・投稿者名・作成日時・更新日時とする。当該投稿の投稿者がログイン中の場合に限り、編集・削除ボタンを表示する。
-
3.4:投稿編集機能
ログイン済みユーザーは、自身が作成した投稿のタイトルおよび本文を編集できる。他ユーザーの投稿に対する編集操作はサーバーサイドでも拒否し、403エラーを返却する。バリデーションルールはF-01と同一とする。編集完了後は当該投稿の詳細ページへリダイレクトする。
-
3.5:投稿削除機能
ログイン済みユーザーは、自身が作成した投稿を削除できる。削除操作は確認ダイアログを経てから実行する。他ユーザーの投稿に対する削除操作はサーバーサイドでも拒否し、403エラーを返却する。削除完了後は一覧ページへリダイレクトする。
-
3.6:ユーザー認証機能
ユーザーはメールアドレスとパスワードによってログイン・ログアウトができる。パスワードはハッシュ関数でハッシュ化した上でDBに保管し、平文保存は禁止する。ログイン失敗時は認証失敗のみを通知し、メールアドレスの存否を推測できる情報(例:「このメールアドレスは登録されていません」)は返却しない。セッションはサーバーサイドで管理し、ログアウト時にセッションを無効化する。
4. 非機能要件
4.1 可用性要件
-
4.1.1:目標稼働率
月間稼働率99.9%以上(月間最大ダウンタイム約44分)を目標とする。計画メンテナンス時間は除外して計算する。
99.99%以上を目指す場合はマルチリージョン構成が必要となりコストが大幅に増加するため、本システムの目的・規模を踏まえ99.9%を採用する。
-
4.1.2:単一障害点(SPOF)の排除
EC2・RDSは、いずれも2つのアベイラビリティゾーンに分散配置するマルチAZ構成を必須とする。
-
4.1.3:自動フェイルオーバー
RDSはマルチAZ配置によりスタンバイインスタンスへの自動フェイルオーバーを実装する。フェイルオーバーのRTOは60秒以内とする。EC2の異常インスタンスはALBヘルスチェックとAuto Scalingの連携によって自動的に切り替えを行う。
-
4.1.4:ヘルスチェック設定
ALBのヘルスチェックはHTTPで/healthエンドポイントに対して30秒間隔で実行し、2回連続失敗でUnhealthy判定、3回連続成功でHealthy復帰とする。Auto ScalingはALBのヘルスチェック結果と連動して異常インスタンスの置換を実行する。
4.2 性能要件
4.2.1:レスポンスタイム
通常負荷時(同時接続50ユーザー以下)において、一覧ページおよび詳細ページの初回ロード完了は3秒以内とする。CloudFrontキャッシュが有効な静的コンテンツは1秒以内を目標とする。
4.2.2:スループット
ピーク時の同時接続ユーザー数は最大100ユーザーとし、この条件下でもレスポンスタイム要件を満たすこと。想定スループットは最大50 RPS(リクエスト/秒)とする。
4.2.3:スケーラビリティ
Auto ScalingのスケールアウトポリシーはCPU使用率60%超で発動し、最大インスタンス台数は4台(最小1台・希望2台)とする。スケールアウト時のクールダウンは300秒、スケールイン時は600秒とし、過剰な増減を防ぐ。
4.2.4:静的コンテンツのキャッシュ
静的コンテンツはTTL 86,400秒(24時間)でエッジキャッシュする。動的コンテンツ(APIレスポンス)はキャッシュ対象外とし、TTL 0秒に設定する。
4.3 セキュリティ要件
4.3.1:通信の暗号化
クライアントとCloudFront間の通信はHTTPS(TLS 1.2以上)に限定し、HTTPアクセスはHTTPSへ301リダイレクトする。CloudFrontとALB間の通信もHTTPSで暗号化する。SSL/TLS証明書はACMで発行・管理し、自動更新を有効化する。
4.3.2:Webアプリケーションファイアウォール
AWS WAF v2をCloudFrontに紐付け、以下のマネージドルールグループを有効化する。
| ルールグループ | 目的 |
|---|---|
| AWSManagedRulesSQLiRuleSet | SQLインジェクション対策 |
| AWSManagedRulesCommonRuleSet | XSSを含む一般的な脅威対策 |
| AWSManagedRulesAmazonIpReputationList | 既知の悪意あるIPアドレスのブロック |
WAFのリクエストログはCloudWatch Logsに保管する。
4.3.3:シークレット情報の管理
DB接続情報(ホスト名・ポート・ユーザー名・パスワード)およびアプリケーションで使用するAPIキー等の機密情報はAWS Secrets Managerで一元管理する。設定ファイル・ソースコード・環境変数への平文記載は禁止する。Secrets ManagerへのアクセスはVPCエンドポイント経由に限定する。
4.3.4:ネットワーク分離
EC2インスタンスおよびRDSインスタンスはプライベートサブネットに配置し、インターネットゲートウェイから直接到達できない構成とする。セキュリティグループは最小権限の原則に従い、以下の通信のみを許可する。サービス間の通信はCIDRベースではなくセキュリティグループIDを参照ソースとして指定する。
| レイヤー | 許可ルール |
|---|---|
| ALB | 443/80ポートへのインターネットからのインバウンド |
| EC2 | ALBセキュリティグループからの80番ポートのみ |
| RDS | EC2セキュリティグループからの3306番ポートのみ |
4.3.5:IAM最小権限
EC2インスタンスにアタッチするIAMロールは、以下の権限のみ付与する。
- Secrets Manager特定ARNへのGetSecretValue
- CloudWatch Logsへのログ書き込み
- Systems Manager Session Manager接続
ワイルドカードによるリソース指定は原則禁止とし、特定リソースARNに限定する。IAMユーザーへのプログラムアクセスキー発行は禁止し、ロールベースのアクセスに統一する。
4.3.6:不正アクセス対策
SSH(22番ポート)へのインターネットからの直接接続を禁止する。EC2への管理接続はAWS Systems Manager Session Managerを介したセッション接続のみとする。接続対策はセキュリティグループにて管理。
4.4 運用・保守要件
4.4.1:メトリクス監視
CloudWatchにより以下のメトリクスを収集・監視する。
| 対象 | 監視メトリクス |
|---|---|
| EC2 | CPU使用率・メモリ使用率・ディスク使用率(CloudWatch Agentで収集) |
| ALB | TargetResponseTime・HTTPCode_Target_5XX_Count・RequestCount |
| RDS | CPUUtilization・DatabaseConnections・FreeableMemory・FreeStorageSpace |
4.4.2:アラート通知
以下の閾値を超過した場合にCloudWatch AlarmがSNSトピックへ通知を発行し、登録されたメールアドレスへアラートを送信する。
| 条件 | 閾値 |
|---|---|
| EC2 CPU使用率 | 5分間継続して80%超 |
| ALB 5xxエラーレート | 1分間で1%超 |
| RDS CPU使用率 | 5分間継続して80%超 |
| RDS 空きストレージ | 20GB未満 |
4.4.3:ログ管理
NginxのアクセスログおよびエラーログはCloudWatch Agentによりリアルタイムに収集し、ロググループ /ec2/nginx/access および /ec2/nginx/error に保管する。
アプリケーションログは /app/application に保管する。ALBアクセスログはS3バケットへ出力する。保持期間はCloudWatch Logsで90日、S3で365日とする。
システムログの監視は対象外とする。
4.4.4:バックアップ・リストア
RDSの自動バックアップを有効化し、バックアップウィンドウは毎日03:00〜04:00 JST(18:00〜19:00 UTC)、保持期間は7日間とする。メンテナンスウィンドウは毎週月曜日04:00〜05:00 JSTとする。Point-in-Time Recovery(PITR)を有効化し、任意の時点へのリストアが可能な状態を維持する。リストア手順書は運用設計書に記載し、四半期に1回のリストア訓練を実施する。
4.4.5:変更管理
インフラへの変更作業は、事前に変更内容・影響範囲・ロールバック手順を記載した作業手順書を作成し、レビューを経た上で実施する。Terraformを用いたIaC化以降は、インフラ変更をコードレビューおよびplan確認のプロセスを経て適用することを原則とする。作業記録(実施日時・作業者・変更内容・結果)は別途管理台帳に残す。
4.4.6:コスト管理
AWS Budgetsにより月次コストの予算アラートを設定し、予算の80%到達時および100%到達時にメール通知を行う。非稼働時間帯(深夜帯)はEC2インスタンスのスケールインにより稼働コストを最適化する。
5. 制約条件
- デプロイ先リージョンはap-northeast-1(東京リージョン)に限定する
- RDBMSはMySQL 8.0を採用する
- アプリケーションフレームワークの選定はインフラ設計に影響を与えない範囲で自由とする
6. 前提条件
- AWSアカウントは取得済みであり、課金設定・MFA設定・IAM管理者ユーザーの設定が完了していること
- 本シリーズを通じて発生するAWSの利用コストは許容範囲内であること
補足:主要コンポーネントの設計根拠
要件定義の段階では「何を実現するか」を定義し、「なぜその構成か」の詳細は基本設計書(第2回)に委ねる。ここでは主要な設計判断の根拠を簡潔に補足する。
CloudFrontをALBの前段に置く理由
HTTPS終端をCloudFrontで行うことでALB以降の内部通信をシンプルに保つ。WAFをCloudFrontに紐付けることで、悪意あるリクエストをALBに到達させる前にブロックできる。またCloudFrontのキャッシュにより、静的コンテンツの配信コストとレイテンシを削減できる。
EC2をプライベートサブネットに置く理由
インターネットから直接到達できない場所に配置することでアタックサーフェスを最小化する。外部からのリクエストは必ずCloudFront → ALBを経由させる設計とする。
RDSをマルチAZ構成にする理由
シングルAZ構成ではAZ障害発生時にDBが利用不可となる。マルチAZ構成によりスタンバイインスタンスへの自動フェイルオーバーが機能し、可用性要件(99.9%以上)を満たす。
次回予告
次回は 第2回:基本設計編 です。
- リージョン・AZ選定の考え方
- 各AWSサービスの採用理由と比較検討
- 全体アーキテクチャの方針決定