はじめに
まただいぶ時間が空きましたね(笑)
これまで、個人開発アプリをAWS上に公開するためのTerraform Packを作る過程を記事にしてきました。
前回までは、EC2単体でWebアプリを公開する構成や、SSM Session Manager、ALB、HTTPS、Auto Scaling Groupまわりを中心に整理してきました。
今回はそこから一歩進めて、EC2+DB構成について書きます。
Webアプリを少し本格的に作ろうとすると、ほぼ確実にDBが必要になります。
ユーザー情報を保存したり、投稿データを残したり、問い合わせ履歴や注文状態を管理したり。
DBが入るだけで、一気に「ちゃんとしたアプリ感」が出ます。
ただ、最初は正直こう思っていました。
DBを追加すればいいだけでしょ?
ところが実際にTerraformで構成を作り始めると、思ったより考えることが多かったです。
特に悩んだのが、アプリケーション用EC2をどこに置くかです。
Public Subnetに置くのか
Private Subnetに置くのか
NAT Gatewayを使うのか
このあたりで、かなり頭を抱えました。
今回は、個人開発向けのEC2+DB構成で、なぜ Public構成 と Private+NAT構成 の両方を用意したのかを整理します。
今回作ったEC2+DB構成
今回のEC2+DB構成では、DBとして以下を選べるようにしました。
- RDS MySQL
- RDS PostgreSQL
- DynamoDB
さらに、アプリケーション側のネットワーク構成として、以下の2パターンを用意しました。
- 低コスト構成:Public構成
- セキュア構成:Private+NAT構成
組み合わせとしては、合計6構成です。
| アプリ構成 | DB |
|---|---|
| Public構成 | RDS MySQL |
| Public構成 | RDS PostgreSQL |
| Public構成 | DynamoDB |
| Private+NAT構成 | RDS MySQL |
| Private+NAT構成 | RDS PostgreSQL |
| Private+NAT構成 | DynamoDB |
最初は「DB付きなら全部Private Subnetでよくない?」と思っていました。
ただ、個人開発向けとして考えると、必ずしもそれだけが正解ではありませんでした。
全体構成のイメージ
今回の構成をざっくり整理すると、以下のような形です。
少し立体的に見ると、Web公開の入口、アプリケーション層、DB層、外部API連携がそれぞれ分かれます。
Webアプリでは、ユーザーからのアクセスだけでなく、アプリケーション側から外部へ通信したい場面があります。
例えば、決済APIを叩いたり、外部サービスと連携したり、OSパッケージを更新したり。
この「外へ出る通信」をどう扱うかで、Public構成とPrivate+NAT構成の違いが出てきます。
Public構成とは
Public構成では、アプリケーション用EC2をPublic Subnetに配置します。
この構成では、EC2がPublic Subnetにいるため、Internet Gatewayを経由して外部へ通信できます。
ここで大事なのは、Public Subnetに置く = 何でも外部公開する ではないということです。
実際にはSecurity Groupで通信元やポートを制御します。
例えば、アプリケーションEC2への通信はALBからのHTTP通信に限定し、人間の接続はSSM Session Managerを利用してSSHポートを開けない、といった形です。
Public構成のメリット
Public構成のメリットは、主にコストと分かりやすさです。
- NAT Gatewayが不要
- 構成が比較的シンプル
- 外部APIへ通信しやすい
個人開発では、月額コストがかなり重要です。
NAT Gatewayは便利ですが、常時起動するとそれなりに料金がかかります。
まだ売上がない段階や、ポートフォリオ用途で公開したい段階だと、この固定費が地味に重いです。
「AWSを使いたいけど、毎月の料金が怖い」
これは個人開発あるあるだと思います。
自分もまさにそこを気にしながら構成を考えていました。
Public構成の注意点
一方で、Public SubnetにアプリEC2を置く以上、設計を雑にすると危険です。
特に気をつけるべきなのはこのあたりです。
- SSHを開けず、SSM Session Managerを使う
- Security GroupでALBからの通信に限定する
- DBはPublicにしない
Public構成は「何も考えなくてよい構成」ではありません。
あくまで、コストと運用負荷を抑える代わりに、Security GroupやSSMなどで最低限の安全性を確保する構成です。
Private+NAT構成とは
Private+NAT構成では、アプリケーション用EC2をPrivate Subnetに配置します。
ユーザーからの入口はALBに集約し、アプリケーションEC2はインターネットから直接到達できない場所に置きます。
EC2から外部APIやパッケージ取得などを行いたい場合は、NAT Gatewayを経由します。
Private+NAT構成のメリット
Private+NAT構成のメリットは、アプリケーションEC2をインターネットから直接触らせないことです。
- 公開入口をALBに集約できる
- EC2へ直接到達されにくい
- 本番運用向けとして説明しやすい
構成としてはこちらの方がきれいです。
ユーザーアクセスはALBで受ける。
アプリケーションEC2はPrivate Subnetに置く。
DBもPrivate Subnetに置く。
外部通信が必要な場合だけNAT Gatewayを使う。
この流れは、いかにも本番構成という感じがします。
Private+NAT構成の注意点
一方で、NAT Gatewayにはコストがかかります。
個人開発でまだ売上がない状態だと、ここがかなり気になります。
また、構成としてもPublic構成より理解する要素が増えます。
Public Subnet、Private Subnet、Route Table、NAT Gateway、ALB、Security Group、DB Subnet。
学習としては非常に良いのですが、最初から全員にこの構成を強制すると、個人開発者には少し重くなると感じました。
Public構成とPrivate+NAT構成の違い
2つを並べると、違いはかなり分かりやすくなります。
Public構成は、EC2がPublic Subnetにいるため外部通信しやすいです。
Private+NAT構成は、EC2をPrivate Subnetに置きつつ、外部通信はNAT Gateway経由にします。
どちらもDBはPrivate側に置く想定です。
アプリEC2の置き場所と、外部通信の出し方が大きな違いです。
なぜ両方用意したのか
理由は、個人開発では セキュリティだけでなくコストも要件になる からです。
業務システムや大規模サービスであれば、Private Subnetにアプリを置き、NAT Gatewayを使い、監視や冗長化もしっかり入れる判断が自然だと思います。
ただ、個人開発の場合は事情が違います。
まだ売上がない段階で、毎月のAWS利用料だけが増えていくと、かなりしんどいです。
せっかくアプリを作っても、維持費が理由で止めたくなることもあります。
だからこそ、個人開発では「理想構成」だけではなく、「続けられる構成」も大事だと考えました。
| 構成 | 向いているケース |
|---|---|
| Public構成 | 低コストで始めたい、まず公開したい |
| Private+NAT構成 | セキュリティを重視したい、本番運用を意識したい |
どちらが常に正解、という話ではありません。
扱うデータ、サービス規模、予算、運用できる人のスキルによって、選ぶべき構成は変わります。
そのため、今回のEC2+DB構成では、あえて両方を用意しました。
DBをMySQL / PostgreSQL / DynamoDBから選べるようにした理由
DBも1種類に固定しませんでした。
MySQLは情報が多く、個人開発でも扱いやすいRDBです。
PostgreSQLは、PostgreSQL前提のアプリや、少し高度な機能を使いたい場合に選びやすいです。
DynamoDBは、注文管理や状態管理のようにアクセスパターンがある程度決まっている場合に向いています。
逆に、DynamoDBはRDBのようなJOINや柔軟な検索を前提にすると難しくなります。
なので、「DBなら何でも同じ」という扱いにはしませんでした。
利用者が作りたいアプリに合わせて選べるようにしたかった、というのが理由です。
DB付き構成で特に気をつけたこと
DB付き構成では、DBを追加するだけで考えることが一気に増えます。
特に気をつけたのはこの3つです。
- DBをPublicにしない
- Security Groupで接続元を絞る
- 接続手順と料金目安を用意する
アプリEC2がPublic構成であっても、DBまでPublicにする必要はありません。
基本的にはDBはPrivate Subnet側に置き、アプリケーションからのみ接続させる方針です。
また、DBのSecurity Groupでは、アプリケーションEC2からの接続だけを許可します。
MySQLなら3306、PostgreSQLなら5432です。
そして、DB付き構成は「作れた」だけでは足りません。
利用者が自分のアプリからDBへ接続できる必要があります。
そのため、接続手順、サンプルCRUD、料金目安も用意しました。
正直ここはかなり地味ですが、商品として考えるとかなり大事だと思っています。
実際に検証したこと
今回、EC2+DB構成ではPublic構成とPrivate+NAT構成、それぞれでMySQL、PostgreSQL、DynamoDBを検証しました。
合計6構成です。
検証では、Terraform applyが成功すること、EC2からDBへ接続できること、サンプルCRUDが動くこと、配布用ZIPに必要ファイルが含まれていることを確認しました。
特にDB接続まわりは、ドキュメントだけでは不安だったので、実際にAWS上で動かして確認しました。
「理論上できるはず」と「実際に接続できた」は、やっぱり安心感が違います。
個人開発では「正解」より「選べること」が大事
今回かなり感じたのは、個人開発向けのAWS構成では、必ずしも1つの正解に寄せきらない方がよいということです。
セキュリティだけを考えるなら、Private Subnetに寄せた構成を標準にしたくなります。
ただ、個人開発ではコストが重くなると続けられません。
逆に、コストだけを考えて簡単な構成にしすぎると、本番運用として不安が残ります。
だから今回は、低コストで始めたい人向けのPublic構成と、セキュリティを重視したい人向けのPrivate+NAT構成を分けました。
個人開発では、アプリの種類も、予算も、技術レベルも、人によってかなり違います。
だからこそ、構成を選べるようにしておくことが大事だと思いました。
まとめ
今回は、個人開発向けのEC2+DB構成で、Public構成とPrivate+NAT構成を分けた理由を書きました。
Public構成は、低コストで始めやすく、外部API連携もしやすい構成です。
一方で、Security GroupやSSMを使って、EC2やDBを雑に公開しない設計が必要です。
Private+NAT構成は、アプリケーションEC2をPrivate Subnetに置けるため、本番運用向けとして説明しやすい構成です。
ただし、NAT Gatewayのコストや構成理解の難しさがあります。
個人開発では、常に一番セキュアな構成だけが正解とは限りません。
もちろんセキュリティは大事です。
ただ、それと同じくらい、継続できるコスト感も大事です。
今回のEC2+DB構成では、そのバランスを取るために、Public構成とPrivate+NAT構成の両方を用意しました。
おまけ
今回の考え方をもとに、個人開発者向けのTerraform Packとして、EC2+DB構成を作っています。
DBはMySQL、PostgreSQL、DynamoDBから選択できるようにし、ネットワーク構成も低コスト構成とセキュア構成を選べるようにしました。
まだまだ改善しながらですが、個人開発者がAWS上でアプリを公開しやすくなるように、少しずつ整備しています。
毎回思いますが、AWSは「作る」より「どう説明して、どう続けられる構成にするか」の方が難しいですね(笑)
宜しければホームページに構成図などを記載しているので見に来てください。