はじめに
最近の個人開発や、動作検証は基本 TypeScript を使っているのですが、今回は久しぶりに Python を使った開発をしてみたいと思います。
モダンなフレームワークを調べ、RDS に CRUD を行うサーバーレスなバックエンド API を作るためのテンプレートを作ってみました。
インフラは TypeScript(CDK)、アプリは Python(FastAPI)という珍しい構成かもしれませんが、紹介します!
この記事で学べること
- TypeScript と Python が共存するモノレポ構成
- AWS CDK を使ったサーバーレス API のインフラ定義
- FastAPI + SQLModel + Alembic を使った Python API の構成
- ローカル(Docker)から AWS(Lambda + Aurora)まで一貫した開発フロー
前提知識・条件
各 AWS サービスやフレームワークの説明は紹介程度になります。
詳細な使い方については公式ドキュメントをご参照ください。
- AWS CLI と CDK CLI がインストール済み
- Node.js / pnpm / uv / Docker がインストール済み
全体構成
ソースコード
ソースコードは以下格納済みです。
リポジトリ名のタイポはご容赦ください…!
モノレポ構成(packages/cdk / packages/api / packages/db)
このテンプレートは pnpm workspaces を使ったモノレポ構成になっています。
.
├── packages/
│ ├── cdk/ # インフラ定義(TypeScript)
│ ├── api/ # FastAPI アプリ(Python)
│ └── db/ # DB モデル・マイグレーション(Python)
└── docker/ # ローカル開発用 PostgreSQL
モノレポにした理由は主に 2 つあります。
- AI との親和性が良い:コードベースが一箇所にまとまっているため、AI ツールがインフラとアプリの両方のコンテキストを把握しやすくなります
- 各パッケージのコマンドを覚えなくて良い:ルートの
package.jsonにスクリプトをまとめることで、pnpm cdk:deployやpnpm db:seedのように直感的な操作に統一できます
パッケージたちの役割は以下の通りです。
| パッケージ | 言語 | 役割 |
|---|---|---|
packages/cdk |
TypeScript | AWS CDK でインフラを定義 |
packages/api |
Python | FastAPI で REST API を実装 |
packages/db |
Python | SQLModel でモデル定義、Alembic でマイグレーション管理 |
API が Python のため、CDK 側も Python で書くべきかなと悩みましたが、CDK は TypeScript が最も情報が多く書きやすいため TypeScript を採用。
API と DB は Python で統一し、db パッケージを api から共有する構成にしています。
アーキテクチャ図
今回は話題のdraw.io MCP で構成図を書いてみました。(新しいAWSアイコンがうまく使えなかったです)
シンプルな構成としていますが、
クライアントからのリクエストは API Gateway → Lambda → Aurora Serverless v2 の順に流れます。
ローカル PC からは SSM ポートフォワード経由で踏み台サーバを通じて Aurora に直接接続できます。
(補足)RDS Data APIの採用について
Aurora には RDS Data API という HTTP 経由で SQL を実行できる接続方法もあります。
VPC 内に Lambda を置かなくて済むためシンプルな構成になりますが、
今回は SQLAlchemy / SQLModel を利用したかったので、通常の接続方法を採用しました。
VPC に Lambda を置くと、リソース(ENI(Elastic Network Interface))の削除に非常に時間がかかるなどデメリットもあるので、 RDS Data API も有力な選択肢です。
また、一部制限もあるので採用される際は事前に目を通しておくことをおすすめします。
(補足)RDS Proxy の採用について
Lambda から RDS に接続する際、コネクションプールの枯渇を防ぐために RDS Proxy を挟む構成も候補になります。
ただし Aurora Serverless v2 では RDS Proxy は利用可能ですが、コスト面での追加が発生します。
今回はテンプレートとしてシンプルに保ちたかったため採用しませんでした。
こちらも制限事項があるので、以下をご参照ください。
採用技術・フレームワーク紹介
次に採用した技術・フレームワークを簡単に紹介していきます。
AWS CDK(TypeScript)
AWS CDK(Cloud Development Kit)は、TypeScript などのプログラミング言語で AWS インフラを定義できるツールです。
YAML を手書きする CloudFormation と違い、型補完が効いて書きやすく、ループや条件分岐も使えます。
以前紹介記事を書いたので紹介しておきます。
AWS Lambda / Amazon API Gateway
API をサーバーレスで構築する際の王道の組み合わせです。
Lambda はサーバーレスでコードを実行できる AWS のサービスです。
サーバーの管理が不要で、リクエストがあったときだけ起動します。
API Gateway は Lambda の前段に置く HTTP エンドポイントで、URL のルーティングやスロットリングを担いますが、今回はプロキシ統合を利用しているので、複雑なことはほぼしていません。
Aurora Serverless v2
Aurora Serverless v2 は、アクセス量に応じて自動でスケールする RDS です。
今回は PostgreSQL 互換を利用しています。
使った分だけ課金されるため、開発環境や低トラフィックな API でも利用可能です。
最小キャパシティを 0 に設定すると、アイドル時のコストをほぼゼロにできるのが良いですね。
FastAPI
FastAPI は Python の高速な Web フレームワークです。
型ヒントをベースに自動でバリデーション(Pydantic)と OpenAPI ドキュメントを生成してくれるのが特徴です。
FastAPI アプリは Mangum というライブラリを使って Lambda に対応させています。
以下のように非常に少ないコードで API を実装できます。
from fastapi import FastAPI
from mangum import Mangum
app = FastAPI()
handler = Mangum(app) # Lambda ハンドラー
@app.get("/")
def read_root():
return {"message": "Hello"}
SQLModel
SQLModel は SQLAlchemy と Pydantic を統合した O/R マッパです。
FastAPI と同じ作者が作成しており、モデル定義が一箇所で済み、DB テーブルの定義と API のスキーマを兼ねられます。
Alembic
Alembic は SQLAlchemy 向けのマイグレーションツールです。
コマンド実行するだけで、モデルの差分を検知して自動でマイグレーションファイルを生成してくれます。
手動で SQL を書く必要がなく、モデルを変更したらコマンド一発で DB に反映できるのが気に入っています。
最近この仕組みを TypeScript の Drizzle を使って利用していますが、一度慣れると手放せなくなりますね。
uv
uv は Rust 製の高速な Python パッケージマネージャーです。
pip と比べて圧倒的に速く、仮想環境の作成も楽で、uv sync のみで仮想環境のセットアップが完了します。
pnpm
pnpm は高速な Node.js パッケージマネージャーです。
npm や yarn と比べてディスク使用量が少なく、インストールが速いこと特徴です。
今回はモノレポ管理に pnpm workspaces を使っています。
ただ早いだけではなくセキュリティ対策にもなるのでおすすめです!
やってみた
では、開発の流れを紹介していきます。
各種作業でコマンドを入力するのが面倒なので、基本スクリプトで対応しています。
今回使うスクリプトは以下の通りです。
| コマンド | 内容 | 実際のコマンド |
|---|---|---|
pnpm setup:node |
Node.js 依存関係のインストール | pnpm install |
pnpm setup:python |
Python 仮想環境の作成と依存関係のインストール | cd packages/db && uv sync && cd ../api && uv sync |
pnpm docker:up |
ローカル PostgreSQL の起動 | cd docker && ./start.sh |
pnpm docker:down |
ローカル PostgreSQL の停止 | cd docker && ./stop.sh |
pnpm db:migrate |
マイグレーションの適用 | uv run alembic upgrade head |
pnpm db:seed |
シードデータの投入 | uv run python scripts/seed.py |
pnpm db:generate |
マイグレーションファイルの生成 | uv run alembic revision --autogenerate -m "メッセージ" |
pnpm api:dev |
API の開発サーバー起動 | uv run uvicorn src.main:app --reload --host 0.0.0.0 --port 8000 |
pnpm cdk:deploy |
AWS へのデプロイ | cdk deploy |
pnpm cdk:destroy |
AWS リソースの削除 | cdk destroy |
ローカル開発の流れ
- 依存関係のインストール、仮想環境の作成を実行します
pnpm setup:node
pnpm setup:python
- Docker で PostgreSQL を起動します
pnpm docker:up
-
.envファイルを作成します
cp packages/db/.env.example packages/db/.env
cp packages/api/.env.example packages/api/.env
Docker で起動した PostgreSQL に接続するため、デフォルト値のままで動作します。
DATABASE_URL=postgresql+psycopg://postgres:devpassword123@localhost:5432/dev
- マイグレーションを実行します
pnpm db:migrate
- シードデータを投入します
pnpm db:seed
- API を起動します
pnpm api:dev
http://localhost:8000/docs にアクセスすると Swagger UI が開き、API を試せます。
モデルの更新・DB への反映
モデルを変更した場合は、マイグレーションファイルを生成して適用します。
-
packages/db/src/db/models/配下のモデルを編集します。 -
マイグレーションファイルを自動生成します。
pnpm db:generate "add_description_to_todos"
Alembic がモデルの差分を検知して、alembic/versions/ にマイグレーションファイルを生成します。
- 生成されたファイルを確認して、マイグレーションを適用します。
pnpm db:migrate
AWS にデプロイしてみる
- デプロイします
なお、CDK を対象リージョンで初めて利用する際は bootstrap が別途必要です。
pnpm cdk:deploy
- デプロイが完了すると、ターミナルに API Gateway の URL が出力されます
Outputs:
CdkStack.ApiUrl = https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/dev/
- この URL にアクセスして動作確認できます。
curl https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/dev/health
# {"status":"ok","database":"connected"}
Aurora への migrate / seed
デプロイ後、Aurora に対して migrate / seed を実行するには SSM ポートフォワードにて、踏み台経由で接続します。
デプロイ完了時に以下のような出力が表示されます。
CdkStack.PortForwardCommand = aws ssm start-session --region ap-northeast-1 --target i-xxxxxxxxxx --document-name AWS-StartPortForwardingSessionToRemoteHost --parameters '{"portNumber":["5432"], "localPortNumber":["5432"], "host": ["xxxx.ap-northeast-1.rds.amazonaws.com"]}'
CdkStack.DatabaseSecretsCommand = aws secretsmanager get-secret-value --secret-id AuroraClusterSecret-xxxxxxxx --region ap-northeast-1
-
DatabaseSecretsCommandをそのまま実行して DB 認証情報を取得し、packages/db/.envに設定します -
別ターミナルで
PortForwardCommandをそのまま実行してポートフォワードを開始します -
ポートフォワードが繋がった状態で migrate / seed を実行します
pnpm db:migrate
pnpm db:seed
まとめ
FastAPI × Aurora Serverless v2 を CDK でデプロイするテンプレートを紹介しました。
- TypeScript(CDK)と Python(API/DB)をモノレポで共存させる構成
-
cdk deploy一発でインフラとアプリが揃う - ローカルは Docker、本番は Lambda + Aurora で環境差異を最小化
テンプレートとして使えるよう設計しているので、モデルを追加したりエンドポイントを増やしたりするだけで自分のプロジェクトに応用できます。
個人的には SQLModelのモデル定義や、FastAPI の Swagger UI 自動生成には驚きました。
とっても便利ですね。
今後何か使うことがあったらもっと発展させていきたいと思います!

