初めに
WebアプリをAWS上で構築・運用していくための構成について考えてみた。
AWS上でアプリを構築していくうえでどういったことを考えながら構成を検討していくべきなのかを意識して検討してみた。
アプリの構成を一から検討することで今まで見えてこなかったもの(クラウドエンジニアに求められるもの・設計時の重要なこと)があるので、最後にまとめました。
中盤はどういった値を入れるか等書いていて読んでもつまらないようなものなので、最後のまとめだけでも見てもらえると、今回伝えたいことはお伝えできるかなと、、、
それでは、実際にアプリ開発の話に入っていきましょう!!
筆者はお酒が大好きなので、お酒の投稿を主とするSNSを今回作ってみたいと思う。
イメージはXやインスタグラムのような気軽に投稿できるSNSを目指し、投稿機能・いいね等をできるようにする。
本記事では、どんなアプリを作るのか、そして AWS 上でどのような構成にするのかをまとめていく。今回はAWSへの理解を深めることがメインなので、アプリに関してはさらっとだけ触れる程度ですのでご了承ください、、
アプリ
今回作成していくWebアプリの概要や使用するフレームワーク等についてまとめていく。今回はAWS上で動くWebアプリを目指し、フロントエンドとバックエンドは分離して開発・実装を行う。
アプリ概要
作成するWebアプリはお酒特化型のSNSである。
主な機能は、画像のアップロードやいいね等下記の機能の実装を目指す。
- X(旧Twitter)風のタイムライン
- 写真付き投稿機能
- コメント・いいね
- プロフィール
- お酒の種類や銘柄で検索
- ユーザー登録・認証(メールアドレスとパスワード認証、多要素認証はとりあえず実装なし)
以下はあったらいいなって機能。
- おすすめ表示やランキング表示
フロントエンド
今回は、AWS上でWebアプリを動かすということが目的なため、フロントエンドはこだわらず、簡易的なものを作成予定。アプリ概要で記載した機能を実装できる最小限のものとする。
Next.jsを使用してフロントエンドを作成する。Next.jsを使用する意図として以下がある。
- React ベースで UI を作りやすい
- SSG(静的生成)に対応しており、S3 + CloudFront と相性が良い
- Cognito との連携情報が豊富で実装しやすい
- 将来的に SSR が必要になっても対応できる柔軟性がある
作成予定のフロントエンドは下記の通り。簡易X・Instagramってイメージ。
- タイムライン画面(みんなの記事が表示される画面)
- 投稿記事画面(コメント・いいねができる投稿された記事の詳細画面)
- 投稿画面(記事を投稿する画面)
- 検索画面(記事について検索できる画面)
- プロフィール(各個人のプロフィール画面)
- ユーザー登録・ログイン画面(ユーザー登録とログイン用の画面)
バックエンド
バックエンドはFastAPIで実装する。SNSはAPI処理が多く、APIに特化していて、高速処理で、Pythonで開発しやすいという点を考慮しFastAPIを利用する。実装する機能は下記の通り。
認証関連
- JWT の検証(Cognito のトークンを検証)
- ログインユーザー情報の取得
※ユーザー登録は Cognito が担当
投稿関連
- 投稿作成
- 投稿削除
- 投稿一覧取得
コメント関連
- コメント作成
- コメント削除
- コメント一覧取得
いいね関連
- いいね追加
- いいね削除
- いいね数取得
プロフィール関連
- プロフィール編集
- フォロー / フォロー解除
- フォロー一覧取得
画像アップロード
- S3 の署名付きURLを発行し、フロントから直接アップロードできるようにする
AWS
アプリ実装のために、今回のアプリ構成に適したAWSリソースについて検討し、まとめていく。
構成図
詳細については後述していくが、今回のAWS構成図は下記のようになる想定。CloudFrontを経由してALB→ECSへの経路とS3への経路を確保する。
CloudFrontの前段にはWAFを実装し、セキュリティを高める。
フロントエンド
フロントエンドには、S3+CloudFrontを採用する。
以下の4つのサービスを候補として検討した。
- S3 + CloudFront
- Amplify Hosting
- ECS (Fargate)
- Lambda@Edge / Lambda SSR
今回のアプリ(BeerSNS)は SSR(Server Side Rendering)が不要で、
Next.js の SSG(Static Site Generation)で十分対応できる。
SNS の画面はほぼ API を叩く CSR(Client Side Rendering)で動くため、
SSR を使うメリットがほとんどない。
そのため、SSR を前提とする ECS や Lambda@Edge はオーバースペックであり、
常時稼働コストも高くなるため採用しない。
Amplify Hosting は Next.js の SSR に対応しており便利だが、
フルマネージドであるがゆえに構成がブラックボックス化しやすい。
また、ビルド時間課金や Lambda@Edge の実行コストなど、予期せぬ料金が発生しやすいといったこともあるため今回は採用しない。
今回のアプリは個人運用でコストを抑えたいこと、
そして AWS の構成を自分で理解しながら構築することが目的であるため、
最もシンプルで安価、かつ構成が明確な S3+CloudFront が最適であると判断した。
※アプリ開発に専念しながら簡単にデプロイしたい場合はAmplify Hostingが向いている気がする。
| サービス | 特徴 | SSR | コスト | 難易度 | 向いてる用途 |
|---|---|---|---|---|---|
| S3 + CloudFront | 静的サイト配信の王道 | ✕(SSGのみ) | ◎ 最安 | ◎ 簡単 | SSG/CSR アプリ |
| Amplify Hosting | Next.js SSR 対応、GitHub連携 | ◎ | ○ | ◎ | SSR/SSG 両方 |
| ECS (Fargate) | Node.js サーバーとして Next.js を動かす | ◎ | ✕ 高い | ✕ 重い | 本格SSR、大規模 |
| Lambda@Edge / Lambda SSR | サーバーレス SSR | ◎ | △ | ✕ 複雑 | 高度なSSR |
バックエンド
バックエンドにはECS on Fargateを採用する。
以下の4つのサービスを候補として検討した。
① ECS on Fargat
メリット
- 常時稼働 API に最適
- Docker そのまま動く
- スケール自動
- VPC 内で安全
- ALB と組み合わせやすい
- RDS との接続が安定
- 運用負荷が低い(サーバーレス)
デメリット
- Lambda よりはコスト高い
- 初期構築は少し複雑
② Lambda + API Gateway
メリット
- コストが安い
- サーバーレスで運用が楽
- 小規模 API に最適
デメリット
- コールドスタートで遅い
- DB コネクション維持が難しい
- 常時稼働 API に不向き
- FastAPI を Lambda 化するのは手間がかかる
③ ECS Express Mode
メリット
- GitHub / ECR から自動デプロイ
- ALB 自動作成
- VPC 自動構築
- HTTPS 自動
- スケール自動
デメリット
- ECSほど細かい制御はできない
- 大規模・複雑な構成(マイクロサービスや複雑なネットワーク要件)には不向き
④ EC2
メリット
- 自由にサーバーをカスタマイズできる
デメリット
- サーバー管理が必要
- パッチ適用
- スケールも手動
- 運用コストが高い
今回はSNSアプリということで、応答速度を意識しないといけない。そのため常時稼働のAPIが必要であり、Lambdaを使用するとコールドスタートの影響でサービスの質が落ちてしまうため、Lambda+API Gatewayは採用しない。
ECS Express Modeは簡単かつ迅速にデプロイできるというメリットはあり、今回の構成では複雑なルーティング等がないため、適しているといえる。しかし今回はAWSへの理解を深めるというところが大きいため、採用しない。
EC2は自由にカスタマイズできるというメリットはあるが、EC2出ないとできないといったことが今回はなく、運用等の管理の手間が増えるだけなため採用しない。
以上の理由から、柔軟性・安定性・実務性・学習効果のバランスが最も優れている ECS Fargate を採用する。
データベース
今回は以下の3つのサービスを利用してデータを管理する。
- RDS(PostgreSQL)
- DynamoDB
- S3
それぞれが役割を分担し、整合性 × 高速性 × コスト最適化を同時に満たす構成となる。
RDS(PostgreSQL)
SNS のコアとなる以下のデータを扱う。
- 投稿
- コメント
- フォロー関係
- 通知
- タグ
- メタデータ(JSON)
これらは リレーションが強く、整合性が重要なデータであるため、RDS を採用する。
また、PostgreSQL を選んだ理由は以下の通り:
- JSONB が強力(柔軟なメタデータを扱える)
- リレーションが強い(JOIN が多い SNS に最適)
- 拡張機能が豊富(pg_trgm など検索に強い)
- FastAPI(Python)との相性が良い
- Aurora はコストが高く、今回の規模では不要
DynamoDB
今回のアプリでは、RDS(PostgreSQL)だけでは性能が足りない部分があるため、
高速アクセスが必要なデータを DynamoDB に任せる構成を採用する。
SNSの特徴として:
- 読み取りが圧倒的に多い
- 更新頻度が高い(いいね数など)
- タイムラインは高速に返す必要がある
これらを RDS だけで処理すると、行ロック・スケール限界・レスポンス低下が発生する。
そのため、以下のようなデータにDynamoDBを利用する。
- いいね数
- 投稿の閲覧数
- タイムラインキャッシュ
- ランキング
- 最近の投稿一覧
※DynamoDBの特徴
メリット
- 読み取りが高速(ミリ秒単位)
- スケール自動
- サーバーレスで運用不要
- いいね数・タイムラインなど更新頻度が高いデータに最適
- RDS の負荷を減らせる
デメリット
- JOIN ができない(リレーションは RDS に任せる)
- クエリが柔軟ではない(設計が重要)
- RDB のような複雑な検索には不向き
S3
投稿やプロフィール等に使用する画像の保存先はS3を使用する。
S3の特徴は
- 低コスト
- 高耐久(11ナイン)
- 容量無制限
- CloudFront と組み合わせて高速配信
- Presigned URL で安全にアップロード
- パブリック禁止要件でも OAC を使えば完全プライベート運用可能
S3 は低コスト・高耐久・容量無制限で、CloudFront と組み合わせることで高速な画像配信が可能で、画像の保存と言ったらS3と考えてよし。
取り扱いデータまとめ
| データの種類 | 保存先 | 理由 |
|---|---|---|
| ユーザー情報 | RDS(PostgreSQL) | リレーションが必要(ユーザー ↔ 投稿、フォローなど) |
| 投稿(本文・メタ情報) | RDS | トランザクション・検索・JOIN が必要 |
| コメント | RDS | 投稿とのリレーションが必要 |
| フォロー関係 | RDS | JOIN が必要、整合性が重要 |
| 通知設定 / 各種設定 | RDS | 永続データでリレーションあり |
| いいね数 | DynamoDB | 更新頻度が高い、ロック回避、読み取りが多い |
| 投稿の閲覧数 | DynamoDB | 高速カウンタ用途、スケールが必要 |
| タイムラインキャッシュ | DynamoDB | 読み取りが圧倒的に多い、高速性が必要 |
| ランキング | DynamoDB | 高速アクセス・更新頻度が高い |
| 最近の投稿一覧 | DynamoDB | キャッシュ用途、読み取り中心 |
| 投稿画像 | S3 | 大容量・安価・耐久性高い、CloudFront と相性抜群 |
| プロフィール画像 | S3 | 同上(画像はすべて S3) |
| 画像の EXIF / メタ情報 | RDS or DynamoDB | 検索用途なら RDS、軽量なら DynamoDB |
セキュリティ要件
通信の保護
通信の暗号化・認証・改ざん検知のためにクライアント(外部)からの通信はすべてHTTPSとし、内部間(ALB⇔ECSなど)はHTTP通信とする。
秘密情報の保存方法
今回使用するデータには下記の秘密情報があり、主にSecretManagerで情報の管理をし漏洩対策を実施。
①アプリケーション側の秘密情報
| 秘密情報 | 説明 | 保存先 |
|---|---|---|
| アプリの内部用トークン | 例:管理者用の内部キー | Secrets Manager |
| Webhook の署名キー | 外部サービスと連携する場合 | Secrets Manager |
| 暗号化キー(AES など) | アプリ内で暗号化する場合 | Secrets Manager |
②インフラ(AWS)側の秘密情報
| 秘密情報 | 説明 | 保存先 |
|---|---|---|
| RDS(PostgreSQL)パスワード | DB 接続に必要 | Secrets Manager |
| 外部 API キー | 例:メール送信サービスなど | Secrets Manager |
| ECS タスクで使う環境変数のうち秘密情報 | DB 接続文字列など | Secrets Manager |
③ユーザーの認証に関する秘密情報
| 秘密情報 | 説明 | 保存先 |
|---|---|---|
| ユーザーパスワード | Cognito がハッシュ化して保存 | Cognito(AWS 管理) |
| リフレッシュトークン | Cognito が管理 | Cognito |
| アクセストークン(JWT) | クライアント側で保持 | クライアント(Secure Storage) |
③のユーザー認証に関する情報は、今回はCognitoでユーザー認証を管理するため、管理はCognitoに行わせる。それ以外の情報はSecretManagerを利用し、管理する。
SecretManagerではRDSパスワードの自動ローテーションを有効化することでパスワードを定期的に変更させる。
SecretManagerの読み取り権限は基本的にユーザーには与えず、実行するECSタスク等に与え不必要に権限を与えないようにする。管理者のみ閲覧できるようにするが、CloudTrailで監査されるようにする。
今回AWSのリソースをterraformで作成する予定だが、SecretManagerに保存する値はterraform上には書き込まず、AWS CLIかWebコンソールから設定値を投入するようにすることで、terraformのstate上に秘密情報が残り漏洩するリスクをなくす。
認証・認可
ユーザーの認証にはAmazon Cognitoを利用する。
Cognitoを利用するとメールアドレス+パスワードでサインアップができるためこの機能を利用し、バックエンド側でCognitoのJWTを検証して認証を行う。検証がOKの場合、user_idをコンテキストに渡すようにする。
認可は、リクエストがユーザー本人かどうかであるかを判別して実装する。下記のようなルールで実装。
- 自分の投稿の編集・削除 →
user_id == post.owner_idのときのみ許可 - 自分のプロフィール編集 →
user_id == profile.user_idのときのみ許可 - いいね → 認証済みユーザーのみ
基本的にすべてのAPIで認証済みのユーザーかどうかを検証して、認可を実装する。
ネットワークセキュリティ
基本設計
AWSでの構成として、VPCを利用してアプリケーション層(ECS等)とデータ層(RDS等)はプライベートサブネットに配置させることで、アプリケーション・データを外部に公開させない。パブリックに公開するものとしては、CloudFrontとALBを利用し、そこからアプリケーションへとアクセスさせるように実装する。S3とDynamoDBはVPC外のサービスになるため、VPC Endpoint経由でアクセスする。
下記のようなイメージ
[インターネット]
│
▼
┌──────────────┐
│ Public Zone │ ← 公開
│ (CloudFront, ALB) │
└──────────────┘
│
▼
┌──────────────┐
│ Private Zone │ ← アプリケーション層(非公開)
│ (ECS, Lambda) │
└──────────────┘
│
▼
┌──────────────┐
│ Data Zone │ ← データ層(非公開)
│ (RDS, DynamoDB, S3) │
└──────────────┘
SG設計
SGに関しては最小限の設計とし、不必要な通信を許可しないようにする。
ALB の SG
| 種類 | 許可 |
|---|---|
| Inbound | 0.0.0.0/0 → 443(HTTPS) |
| Outbound | ECS の SG のみ許可 |
ECS(FastAPI)の SG
| 種類 | 許可 |
|---|---|
| Inbound | ALB → 80 |
| Outbound | RDS の SG、VPC Endpoint のみ |
RDS(PostgreSQL)の SG
| 種類 | 許可 |
|---|---|
| Inbound | ECS → 5432 |
| Outbound | なし(デフォルト) |
WAF
Webアプリは一般に公開し、IP制限等は基本的に設けないため攻撃されるリスクが高まる。
そのため、SQL InjectionやXSS(クロスサイトスクリプティング)といったものからアプリを守るためにWAFを利用する。
今回APIをユーザーが利用できるような設計(記事の投稿等)がありAPIが外部に公開されているということもあり、WAFの重要性が高まる。
コストが少し上がるが、コスト以上に価値があると判断。
ログ取得
セキュリティ要件の一つとしてログ取得項目についてまとめる。
- アプリケーションログ
- インフラログ(AWS)
- セキュリティログ
- 運用ログ
アプリケーションログ
アプリケーションのログとして何を取得するべきか決めるために、ログ取得の目的を明確にし、取得項目を決定していく。
目的
-
障害対応
500が出た際の原因特定など
-
性能・ボトルネック把握
どのエンドポイントの処理が遅いかなど
-
ユーザー行動把握
どのAPIがよく利用されているかなど
ログの利用者
- 開発者
- デバッグや障害時の調査など
- 利用状況の集計等のサービス品質向上など
- 運用担当者
- サービス化後の障害対応など
ログの取得形式
アプリケーションログは最終的にCloudWatchに保存するため、JSON形式で取得する。
取得項目
①リクエストログ
性能把握・障害調査・利用状況分析に使用するログ
| 項目 | 説明 |
|---|---|
| timestamp | ログ発生時刻(ISO8601) |
| method | HTTP メソッド(GET / POST など) |
| path | API パス(例:/posts) |
| status_code | レスポンスステータス |
| latency_ms | API の処理時間(ミリ秒) |
| user_id | Cognito のユーザー ID(sub) |
| request_id / trace_id | リクエスト単位の追跡 ID |
| client_ip | クライアント IP(X-Forwarded-For) |
| user_agent | ブラウザ / アプリ情報 |
②エラーログ
障害時に使用するログ
| 項目 | 説明 |
|---|---|
| timestamp | ログ発生時刻 |
| error_type | 例外の種類(ValueError, HTTPException など) |
| error_message | エラー内容 |
| stack_trace | スタックトレース |
| request_body | リクエスト内容(PII は除外 or マスク) |
| user_id | 操作したユーザー(null の場合も) |
| path | エラーが発生した API パス |
| method | HTTP メソッド |
③ビジネスイベントログ
ユーザー行動分析・品質改善
| 項目 | 説明 |
|---|---|
| timestamp | ログ発生時刻 |
| event | イベント名(例:post_created, like_added) |
| user_id | 操作したユーザー |
| post_id(任意) | 対象の投稿 ID |
| target_user_id(任意) | フォロー対象など |
| cache_hit / cache_miss | タイムラインキャッシュの結果 |
| additional_info | 必要に応じて追加情報(タグ、種類など) |
④パフォーマンスログ
ボトルネックになるAPIの特定等
| 項目 | 説明 |
|---|---|
| timestamp | ログ発生時刻(ISO8601) |
| event |
"db_query", "dynamodb_call", "external_api_call" など |
| path | 呼び出し元 API のパス(例:/posts) |
| method | HTTP メソッド |
| latency_ms | 処理時間(ミリ秒) |
| query(任意) | 実行した SQL(PII を含まない範囲) |
| table_name(任意) | 対象テーブル(RDS/DynamoDB) |
| operation |
"SELECT", "INSERT", "UPDATE" など |
| status | 成功 or 失敗 |
| error_message(失敗時) | エラー内容 |
| user_id | 操作したユーザー(Cognito sub) |
| request_id / trace_id | リクエスト単位で追跡するための ID |
| cache_hit(タイムラインなど) |
true / false
|
⑤セキュリティ関連ログ(認証・認可)
不正アクセス検知・調査
| 項目 | 説明 |
|---|---|
| timestamp | ログ発生時刻 |
| event |
"login_success", "login_failed", "auth_error", "forbidden" など |
| user_id | Cognito の sub(失敗時は null の場合も) |
| ip_address | クライアント IP(X-Forwarded-For) |
| user_agent | ブラウザ情報 |
| path | アクセスされた API |
| method | HTTP メソッド |
| status_code | 401 / 403 / 200 など |
| error_message(失敗時) | 認証失敗理由(PII を含まない) |
| token_valid | JWT が有効かどうか |
| request_id / trace_id | 追跡用 |
インフラログ(AWS)
アプリケーション側ではない、インフラ側のログ取得内容について検討し、まとめていく。
目的
-
障害対応
ECSのタスクが落ちた原因やALBでのエラー原因等、インフラ側の障害対応のため
-
セキュリティ監査
IAMの変更操作やSG(セキュリティグループ)の変更等の設定変更の追跡
-
設定ミスの通知
S3のパブリックアクセスやSGの0.0.0.0/0、CloudTrailの無効化等の検知
-
パフォーマンス監視
ECSやDBのスケール判断、ボトルネック分析
ログの利用者
- 開発者
- 障害対応・性能改善など
- 運用担当者
- ECSのCPU/メモリ監視やRDSの負荷監視、アラーム対応といったサービス安定運用など
- セキュリティ担当
- IAM関連の操作やConfigでの設定ミス検知、不正アクセス等の調査
取得項目
まずはログ調査用にCloudWatch Logsに保存するログをまとめる。
①ECSログ(CloudWatch Logs)
| 項目 | 説明 |
|---|---|
| timestamp | ログ発生時刻 |
| message | アプリ側 stdout/stderr(アプリログがここに入る) |
| task_id | ECS タスク ID |
| container_name | コンテナ名 |
| log_level | INFO / ERROR など |
②ALBアクセスログ(CloudWatch Logs)
| 項目 | 説明 |
|---|---|
| timestamp | アクセス時刻 |
| client_ip | クライアント IP |
| target_ip | ECS タスクの IP |
| request_path | リクエストパス |
| method | HTTP メソッド |
| status_code | レスポンスステータス |
| target_status_code | バックエンドのレスポンス |
| latency_ms | ALB → ECS → ALB の総処理時間 |
| user_agent | クライアント情報 |
③Lambda(非同期処理)ログ(CloudWatch Logs)
| 項目 | 説明 |
|---|---|
| timestamp | 実行時刻 |
| function_name | Lambda 関数名 |
| request_id | Lambda の実行 ID |
| log_level | INFO / ERROR |
| message | 処理内容 |
| error_message | 失敗時のエラー内容 |
| stack_trace | 例外発生時のスタックトレース |
④SQS(デッドレターキュー)ログ(CloudWatch Logs)
| 項目 | 説明 |
|---|---|
| timestamp | メッセージが DLQ に入った時刻 |
| queue_name | キュー名 |
| message_body | 処理失敗したメッセージ |
| receive_count | 何回リトライされたか |
| error_reason | 失敗理由(Lambda 側のログと紐づく) |
次に、スケールやアラームに使用するためCloudWatch Metricsに利用する項目をまとめる。
⑤ECS(CloudWatch Metrics)
| 項目 | 説明 |
|---|---|
| cpu_utilization | CPU 使用率 |
| memory_utilization | メモリ使用率 |
| task_count | 稼働中タスク数 |
⑥RDS(CloudWatch Metrics)
| 項目 | 説明 |
|---|---|
| cpu_utilization | CPU 使用率 |
| db_connections | 接続数 |
| free_storage_space | 空きストレージ |
| read_iops / write_iops | I/O 負荷 |
| deadlocks | デッドロック発生数 |
⑦DynamoDB(CloudWatch Metrics)
| 項目 | 説明 |
|---|---|
| read_capacity_units | 読み取りキャパシティ |
| write_capacity_units | 書き込みキャパシティ |
| throttled_requests | スロットル発生数 |
| successful_request_latency | レイテンシ |
⑧SQS(CloudWatch Metrics)
| 項目 | 説明 |
|---|---|
| approximate_number_of_messages | キュー滞留数 |
| age_of_oldest_message | 最古メッセージの滞留時間 |
次に、CloudTrailでリソースへの操作履歴をログとして保存する。
⑨CloudTrail設定項目
| 設定項目 | 内容 |
|---|---|
| 管理イベント(Management Events) | ON(必須) |
| データイベント(Data Events) | S3 / Lambda のみ必要に応じて ON |
| 読み取りイベント(Read) | ON(推奨) |
| 書き込みイベント(Write) | ON(必須) |
| ログの保存先 | S3 バケット(専用バケットを作成) |
| CloudWatch Logs 連携 | ON(検索しやすくするため) |
| 暗号化(KMS) | ON(セキュリティ強化) |
| ログ保持期間 | S3 側で設定(1年〜無期限) |
最後にAWS Configで検証結果をログとして保存
⑩AWS Config設定内容
| ルール名 | 内容 |
|---|---|
| s3-bucket-public-read-prohibited | S3 がパブリックになっていないか |
| s3-bucket-public-write-prohibited | 書き込みがパブリックになっていないか |
| restricted-ssh | SG が 0.0.0.0/0 で 22 を開けていないか |
| restricted-common-ports | 危険なポートが開いていないか |
| cloudtrail-enabled | CloudTrail が有効か |
| cloudtrail-log-file-validation-enabled | CloudTrail の整合性チェック |
| iam-password-policy | IAM パスワードポリシー |
| rds-storage-encrypted | RDS が暗号化されているか |
| dynamodb-table-encryption-enabled | DynamoDB が暗号化されているか |
まとめ
今回、Webアプリ(X や Instagram のような SNS)を AWS 上で構築するためのアーキテクチャを大まかに整理した。
実際に構成を考えてみて強く感じたのは、AWS の設計はアプリの仕様を理解するところから始まるということ。
- どんなデータを扱うのか
- どれくらいの頻度で読み書きされるのか
- どの部分がスケールするのか
- どのレイヤーにどんなセキュリティが必要なのか
こうしたアプリ要件によって、
使う AWS サービスも、スケール戦略も、ログの取り方もすべて変わってくる。
ECS・EC2・Lambda のどれを選ぶかは一見すると単純な比較に見えるが、
実際には アプリの性質 × コスト × 運用性 × セキュリティ のバランスで決まる。
そして、全体像を把握したうえで最適化していくことこそが、クラウドエンジニアの腕の見せどころだと感じた。
アプリを動かすだけなら誰でもできる。
しかし、無駄のない構成で、強固なセキュリティと運用しやすさを両立させることが本当の価値になる。
そのためには、クラウドエンジニアは クラウド の知識を含め、
- アプリ開発者の視点(どう動くべきか)
- インフラエンジニアの視点(どう守るべきか)
- クラウドアーキテクトの視点(どう最適化するか)
この 3 つの視点を持つ必要がある。
アプリ・インフラ・クラウドを横断して理解できれば、どんなアプリでも最適な構成を設計できるようになる。
今回の Webアプリの構成検討は、その第一歩になったと思う。
次回は実際に今回検討した構成を実際にClaude CodeとTerraformを利用しながらAWS上に構築していく。実際に構築していくうえで設計の甘さ、新たな課題等が出てくるので、それらについてまとめて次回の記事にしようと思うので、乞うご期待!!
記事を最後まで読んでくれた皆さんありがとうございました!!
皆さんの意見も取り入れて、みんなで成長していきたいので、良ければコメントしてくれると嬉しいです!!!
ではまた!
