Skip to content

TypeScript リレーショナルデータベース

Filter this guidePick generator option values to hide sections that don't apply.

このジェネレーターは、Amazon Aurora(PostgreSQL または MySQL)と Prisma ORM を使用した新しいリレーショナルデータベースプロジェクトを作成します。AWS CDK または Terraform を使用してデータベースをプロビジョニングおよび管理するために必要なアプリケーションコードとインフラストラクチャを生成し、宣言的なスキーマ定義、自動マイグレーションデプロイ、型安全な ORM クライアントを提供します。

リレーショナルデータベースの生成

Section titled “リレーショナルデータベースの生成”

新しいリレーショナルデータベースプロジェクトは、2つの方法で生成できます:

Terminal window
pnpm nx g @aws/nx-plugin:ts#rdb
変更されるファイルを確認するためにドライランを実行することもできます
Terminal window
pnpm nx g @aws/nx-plugin:ts#rdb --dry-run
パラメータデフォルト説明
name 必須string-生成するデータベースプロジェクトの名前
directory stringpackagesアプリケーションを保存するディレクトリ
subDirectory string-プロジェクトが配置されるサブディレクトリ。デフォルトではプロジェクト名になります。
infra aurora | noneauroraプロビジョニングするリレーショナルデータベースサービス。
engine postgres | mysqlpostgres選択したサービスで使用するデータベースエンジン
databaseUser stringdbadminデータベース管理者のユーザー名。デフォルトは 'dbadmin' です。
databaseName string-初期データベース名。デフォルトではプロジェクト名になります。
framework prismaprisma生成されるプロジェクトで使用するORMフレームワーク。
iac inherit | cdk | terraforminherit優先するIaCプロバイダー。デフォルトでは、初期選択から継承されます。
preferInstallDependencies booleantrueジェネレーター実行後に依存関係のインストールを優先するかどうか。複数のジェネレーターをバッチ処理する際にインストールを延期する場合はfalseに設定します(後続のジェネレーターがNxプロジェクトグラフを計算できるよう、必要に応じてインストールは実行されます)。最後に一度だけインストールします。

ジェネレーターは、<directory>/<name> ディレクトリに以下のプロジェクト構造を作成します:

  • Directoryprisma
    • Directorymodels
      • example.prisma Example model definition
    • schema.prisma Main Prisma schema (references models)
  • Directorysrc
    • index.ts Project entry point
    • prisma.ts Prisma runtime client wrapper
    • utils.ts Runtime config and secret helpers
    • create-db-user-handler.ts Lambda handler used to create the application database user during deployment
    • migration-handler.ts Lambda handler used to run database migrations during deployment
  • .gitignore Git ignore entries including generated Prisma client output
  • config.json Local development connection details and runtime config key
  • Dockerfile Container image definition for the migration handler
  • package.json Project manifest defining the project’s package name and dependencies
  • project.json Project configuration and build targets
  • prisma.config.ts Configuration for Prisma CLI

ローカル開発スクリプトはすべてのデータベースプロジェクト間で共有され、packages/common/scripts/ に生成されます:

  • Directorypackages/common/scripts/src/rdb
    • pull-image.ts Pulls the database container image
    • start-container.ts Starts a local database container
    • wait-for-postgres-db.ts Waits for the local database to be ready (PostgreSQL)
    • wait-for-mysql-db.ts Waits for the local database to be ready (MySQL)

このジェネレーターは、選択した iac に基づいてインフラストラクチャをコードとして提供するため、関連する CDK コンストラクトまたは Terraform モジュールを含む packages/common にプロジェクトを作成します。

共通のインフラストラクチャコードプロジェクトは、次のように構成されています:

  • Directorypackages/common/constructs
    • Directorysrc
      • Directoryapp/ プロジェクト/ジェネレーター固有のインフラストラクチャ用のコンストラクト
      • Directorycore/ app 内のコンストラクトによって再利用される汎用コンストラクト
      • index.ts app からコンストラクトをエクスポートするエントリーポイント
    • project.json プロジェクトのビルドターゲットと設定
  • Directorypackages/common/constructs/src
    • Directoryapp
      • Directorydbs
        • <name>.ts データベース固有のインフラストラクチャ
    • Directorycore
      • Directoryrdb
        • aurora.ts 汎用 Aurora データベースコンストラクト

デプロイされたデータベースは以下のアーキテクチャを持ちます。デフォルトでは、Amazon RDS Proxy が Aurora クラスターの前に配置され、接続をプールし、IAM 認証を有効にします — 代替案については RDS Proxy を無効にする を参照してください。PostgreSQL または MySQL エンジンのどちらを選択しても、アーキテクチャは同じです。異なるのは Aurora エンジンのフレーバーのみです。

Application(Lambda, Agent, ...)RDS ProxyMigrations LambdaAurora(PostgreSQL or MySQL)Secrets Manager(DB credentials) SQL (IAM auth) Schema migrations Admin credentials

生成されたプロジェクトは Prisma ORM を使用してデータベーススキーマを定義し、型安全なクライアントを生成します。ワークフローはモデルファーストです:データベースプロジェクトの prisma/models/ ディレクトリ配下に Prisma モデルファイルを追加または更新し、それらのモデル変更からマイグレーションを生成します。

User モデルの例:

packages/postgres/prisma/models/user.prisma
model User {
id Int @id @default(autoincrement())
firstName String
lastName String
}

詳細については、公式の Prisma データモデリングガイドを参照してください。

データベースクライアントの生成

Section titled “データベースクライアントの生成”

ジェネレーターは、プロジェクトをビルドするたびに型安全な TypeScript Prisma クライアントを作成するように generate ターゲットを自動的に設定します。クライアントは generated/prisma に書き込まれます(.gitignore に追加されます)。

いつでも手動でクライアントを生成することもできます:

Terminal window
pnpm nx run <your-db-project-name>:generate

ワークスペースルートから Prisma CLI コマンドを実行するには、prisma ターゲットを使用します:

Terminal window
pnpm nx run <project>:prisma generate

src/prisma.ts のランタイムラッパーは以下をエクスポートします:

  • getPrisma() - AWS AppConfig からデータベース接続設定を読み込み、IAM 認証を使用して Prisma クライアントを作成します

クライアントは自動的に以下を行います:

  • RUNTIME_CONFIG_APP_ID 環境変数を使用して AWS AppConfig からデータベース設定を取得します
  • IAM 認証のために AWS RDS Signer 経由で一時的な認証トークンを生成します
  • 証明書検証を伴う SSL/TLS 接続を管理します
  • 永続的なデータベース接続プールを通じて接続プーリングを処理します

prisma/models/ 配下のモデルを追加または更新した後、migrate dev を使用してマイグレーションファイルを生成し、同時にローカルデータベースに適用します。

生成された prisma ターゲットは、実行前に自動的にローカルデータベースコンテナを起動します:

Terminal window
pnpm nx run <project>:prisma migrate dev

ローカルデータベースに適用せずにマイグレーションファイルのみを生成したい場合は、--create-only を追加します:

Terminal window
pnpm nx run <project>:prisma migrate dev --create-only

これにより、スキーマが変更されるたびに prisma/migrations に新しいマイグレーションフォルダが生成されます:

  • Directoryprisma
    • Directorymigrations
      • Directory20260405013911_initial_migrations
        • migration.sql
      • migration_lock.toml
    • schema.prisma

AWS スタックをデプロイすると、生成されたインフラストラクチャが自動的に生成されたマイグレーションをデプロイされたデータベースに適用します。

既存のマイグレーションの適用

Section titled “既存のマイグレーションの適用”

他の開発者が作成したマイグレーションファイルをプルした場合、migrate deploy を使用してそれらの既存のマイグレーションをローカルデータベースに適用します。

Terminal window
pnpm nx run <project>:prisma migrate deploy

このローカル開発フローでは、migrate deploy はマイグレーションファイルをローカルデータベースに適用します。データベースを AWS にデプロイするわけではありません。

生成された prisma ターゲットは Prisma CLI を公開しているため、ローカルデータベースに対して Prisma がサポートする任意のコマンドを実行できます。利用可能なコマンドについては、Prisma CLI リファレンスを参照してください。

Terminal window
pnpm nx run <project>:prisma <prisma-command>

Prisma Studio は、ローカルデータベース用のビジュアルエディタです。テーブルの閲覧、レコードの検査と編集、データのフィルタリング、リレーションのフォロー、組み込みの SQL コンソール経由での生の SQL の実行に使用できます。開発中のマイグレーションの検証やテストデータのシードに便利です。以下で起動します:

Terminal window
pnpm nx run <project>:prisma studio

dev を停止すると(例:Ctrl+C で)、ローカルデータベースコンテナは自動的に削除されますが、名前付きボリュームは保持されるため、再起動してもデータは永続化されます。

任意の TypeScript プロジェクトで、データベースパッケージから getPrisma をインポートし、それを呼び出して型安全な Prisma クライアントを取得します:

import { getPrisma } from '@my-scope/db';
const prisma = await getPrisma();
const users = await prisma.user.findMany({ orderBy: { id: 'asc' } });

getPrisma() は遅延初期化されたキャッシュされたクライアントを返します。同じ Lambda 実行コンテキスト内での後続の呼び出しは、新しい接続を開くのではなく、既存の接続プールを再利用します。

Prisma クライアントは、prisma/models/ スキーマから派生した完全に型付けされたモデルを公開し、データベースから API レスポンスまでエンドツーエンドの型安全性を提供します。

getPrisma() は、実行時に AWS AppConfig からデータベース接続設定を取得します。

リレーショナルデータベースジェネレーターは、選択した iac に基づいて CDK または Terraform インフラストラクチャを作成します。

CDK コンストラクトは common/constructs に作成されます。使用例:

packages/infra/src/stacks/application-stack.ts
import { MyDatabase } from '@my-scope/common-constructs';
export class ApplicationStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);
...
const db = new MyDatabase(this, 'Db', {
vpc,
vpcSubnets: {
subnetType: SubnetType.PRIVATE_ISOLATED,
}
});
}
}

これにより、RDS Proxy を備えた Aurora クラスター、管理者認証情報、アプリケーションデータベースユーザー、ランタイム設定の登録、およびマイグレーションハンドラーがプロビジョニングされます。

生成されたインフラストラクチャは、2つのデータベースユーザーを作成します:

  • 管理者ユーザー - クラスターのプロビジョニング時に作成され、認証情報は AWS Secrets Manager に保存されます
  • アプリケーションユーザー - Lambda カスタムリソースを介して作成され、IAM 認証が有効化され、アプリケーションデータベースに対する DML 権限(SELECT、INSERT、UPDATE、DELETE)が付与されます

アプリケーションユーザーは、ランダムな名前と IAM 認証で自動的に作成されます。生成されたデータベースクライアントは、短期間有効な RDS トークンを使用してこのユーザーとして認証するように既に設定されているため、アプリケーションコードがデータベースパスワードを処理することはありません。

VPC には、パブリックサブネット、エグレスを持つプライベートサブネット、およびプライベート分離サブネットを含める必要があります。データベースはプライベート分離サブネットで実行でき、アプリケーション Lambda 関数は AppConfig などの AWS サービスに到達できるように、エグレスを持つプライベートサブネットで実行する必要があります。

VPC 設定の例については、こちらをクリックしてください。

connection ジェネレーターを使用して、プロジェクトをこのデータベースに接続します。データベースに到達するために必要なインフラストラクチャの配線については、関連するコンピュートタイプ(FastAPI、MCP サーバー、エージェントなど)の接続ガイドを参照してください。

このプロジェクト用にビルドされた Docker イメージは、ECR ホスト版 Trivy イメージから実行される Trivy を使用して脆弱性をスキャンできます。

プロジェクトに trivy ターゲットが追加され、ビルドされたイメージをスキャンし、HIGH または CRITICAL の深刻度の脆弱性が見つかった場合は非ゼロで終了します。生成された Dockerfile は、生成時点でこれらの深刻度の既知の修正可能な脆弱性がないベースイメージを使用し、バンドルされたツール(npm など)をアップグレードしてその状態を維持します。

スキャンはイメージビルドと同じコンテナエンジン(docker または finch)を使用するため、追加のツールは必要ありません。スキャンはイメージが変更された場合にのみ再実行されるため、変更されていないイメージは再スキャンされません。提供される trivy ルートスクリプトは、ワークスペース内のすべてのイメージをスキャンします:

Terminal window
pnpm trivy

特定の脆弱性を抑制したい場合があります。たとえば、まだ修正が利用できず、リスクを許容可能と評価した場合などです。

脆弱性 ID(1 行に 1 つ)をプロジェクトのルート(つまり project.json の隣)にある .trivyignore ファイルに追加します:

.trivyignore
# node-tar arbitrary file write - not exploitable in our usage
CVE-2024-XXXXX

検出結果のフィルタリングの詳細については、Trivy フィルタリングドキュメントを参照してください。

生成されたインフラストラクチャには、デフォルトで RDS Proxy が含まれており、アプリケーションと Aurora クラスターの間に配置されます。RDS Proxy にはいくつかの利点があります:

  • コネクションプーリング - アプリケーションインスタンス間で共有できるデータベース接続のプールを維持し、新しい接続を確立するオーバーヘッドを削減します
  • 接続の回復性 - Aurora インスタンスの交換やメンテナンス中のフェイルオーバーと再接続を自動的に処理します
  • IAM 認証 - IAM ベースのデータベース認証をサポートし、アプリケーションコードでデータベース認証情報を管理する必要がなくなります
  • セキュリティの向上 - すべての接続に対して TLS 暗号化を強制します

次のように RDS プロキシを無効にできます:

packages/infra/src/stacks/application-stack.ts
import { MyDatabase } from '@my-scope/common-constructs';
const db = new MyDatabase(this, 'Db', {
...
enableRdsProxy: false,
});

RDS Proxy が無効になっている場合、アプリケーションは Aurora クラスターエンドポイントに直接接続します。

SSL Requirements When Connecting Without RDS Proxy

Section titled “SSL Requirements When Connecting Without RDS Proxy”

Aurora クラスターに直接接続する場合(RDS Proxy を使用しない場合)、getPrisma() を呼び出すランタイムは Amazon RDS CA バンドルを信頼する必要があります。生成された Prisma クライアントは証明書検証を有効にします。CA バンドルを利用可能にする方法は、データベースに接続するランタイムによって異なります。

Amazon RDS の場合、以下からグローバル CA バンドルを使用します:

https://truststore.pki.rds.amazonaws.com/global/global-bundle.pem

ランタイム用に独自のコンテナイメージを準備する場合は、Dockerfile で RDS CA バンドルをダウンロードし、オペレーティングシステムのトラストストアに追加します。

RUN curl -fsSL "https://truststore.pki.rds.amazonaws.com/global/global-bundle.pem" \
-o /etc/pki/ca-trust/source/anchors/rds-bundle.pem && \
update-ca-trust

Node.js 20 以降のランタイムを使用する Zip 形式の Lambda 関数の場合、NODE_EXTRA_CA_CERTS を設定して Amazon RDS CA バンドルを読み込みます:

packages/infra/src/stacks/application-stack.ts
const api = new Api(this, 'Api', {
integrations: Api.defaultIntegrations(this)
.withDefaultOptions({
environment: {
NODE_EXTRA_CA_CERTS: '/var/runtime/ca-cert.pem',
},
})
.build(),
});

詳細については、AWS Lambda の Amazon RDS 接続の SSL/TLS 要件を参照してください。RDS Proxy を使用する場合、データベースに接続するランタイムで RDS CA バンドルを設定する必要はありません。

Auroraクラスターのライターインスタンスとリーダーインスタンスを設定します。

packages/infra/src/stacks/application-stack.ts
import { MyDatabase } from '@my-scope/common-constructs';
const db = new MyDatabase(this, 'Db', {
...
writer: ClusterInstance.serverlessV2('writer'),
readers: [ClusterInstance.serverlessV2('reader')],
});

ワークロードに合わせて Aurora Serverless v2 のスケーリング制限を制御します。

packages/infra/src/stacks/application-stack.ts
import { MyDatabase } from '@my-scope/common-constructs';
const db = new MyDatabase(this, 'Db', {
...
serverlessV2MinCapacity: 0.5,
serverlessV2MaxCapacity: 8,
});

特定の Aurora エンジンバージョンを固定します。

デフォルトでは、生成されたローカルデータベースコンテナイメージは、デフォルトの Aurora エンジンバージョンと一致します。Aurora エンジンバージョンを変更する場合は、最大限の互換性を得るために、一致するローカルコンテナイメージバージョンも使用することをお勧めします。対応するコミュニティデータベースバージョンを特定するには、AWS リリースノートの Aurora PostgreSQL versions および Aurora MySQL versions を参照してください。

ローカルデータベースイメージは、データベースプロジェクトルートにある生成された config.json ファイルの localDev.image フィールドで設定されます。エンジンバージョンを変更する際は、その値を更新してください。

engine = postgres
packages/infra/src/stacks/application-stack.ts
import { MyDatabase } from '@my-scope/common-constructs';
const db = new MyDatabase(this, 'Db', {
...
engineVersion: AuroraPostgresEngineVersion.VER_17_7,
});
engine = mysql
packages/infra/src/stacks/application-stack.ts
import { MyDatabase } from '@my-scope/common-constructs';
const db = new MyDatabase(this, 'Db', {
...
engineVersion: AuroraMysqlEngineVersion.VER_3_12_0,
});

削除保護はデフォルトで有効になっており(CDKではdeletionProtection: true、Terraformではdeletion_protection = true)、Auroraクラスターを誤って削除することから保護します。

短期間の開発環境やプレビュースタックなど、データベースの削除が想定される環境では、削除保護を無効にすることができます。

packages/infra/src/stacks/application-stack.ts
import { MyDatabase } from '@my-scope/common-constructs';
const db = new MyDatabase(this, 'Db', {
...
deletionProtection: false,
});

CDK コンストラクトはデフォルトで Aurora クラスターを保持します(removalPolicy: RemovalPolicy.RETAIN)。CDK スタックの削除時にクラスターをスナップショットまたは破棄したい場合は、これを変更してください。

RemovalPolicy.DESTROY を使用する場合、クラスターを削除する前に削除保護も無効にする必要があります。

packages/infra/src/stacks/application-stack.ts
import { RemovalPolicy } from 'aws-cdk-lib';
import { MyDatabase } from '@my-scope/common-constructs';
const db = new MyDatabase(this, 'Db', {
...
removalPolicy: RemovalPolicy.SNAPSHOT,
});

データベースをスタックと一緒に削除する必要がある一時的な環境の場合:

packages/infra/src/stacks/application-stack.ts
import { RemovalPolicy } from 'aws-cdk-lib';
import { MyDatabase } from '@my-scope/common-constructs';
const db = new MyDatabase(this, 'Db', {
...
deletionProtection: false,
removalPolicy: RemovalPolicy.DESTROY,
});
engine = postgres

postgresql ログは Aurora PostgreSQL 用にエクスポートされ、ログは DDL ステートメントのみにスコープされています(log_statement=ddl)。そのため、各ステートメントが個別に送信される限り、ステートメントのパラメータ値はログに記録されません。log_statement=ddl は、複数ステートメントのバッチ(例:単一の psql -c "a;b;c" 呼び出し)の生のテキスト全体を、そのバッチ内のいずれかのステートメントが DDL である場合、同じバッチ内の DML 値を含めてそのまま記録します。

engine = mysql

audit および error ログは Aurora MySQL 用にエクスポートされます — general および slowquery は、DML 値を含む完全なステートメントテキストをログに記録するため、意図的に除外されています。Advanced Auditing は接続と DDL にスコープされており(server_audit_events=CONNECT,QUERY_DDL)、ステートメントパラメータ値はログに記録されません。

Performance Insights は、デフォルトで Aurora ライターインスタンスで有効になっています(クラスターの KMS キーで暗号化されます)。Aurora エンジンログもデフォルトで CloudWatch Logs にエクスポートされ、行データを漏洩させることなくスキーマレベルのアクティビティを表示するように設定されています。

必要ない場合は、データベースごとにログエクスポートを無効にします:

packages/infra/src/stacks/application-stack.ts
import { MyDatabase } from '@my-scope/common-constructs';
const db = new MyDatabase(this, 'Db', {
...
enableCloudwatchLogs: false,
enablePerformanceInsights: false,
});

Auroraクラスターとその認証情報シークレットの暗号化に使用されるKMSキーは、デフォルトで自動キーローテーションが有効になっています。セキュリティポリシーで外部的にローテーションを管理している場合は、これを無効にしてください。

packages/infra/src/stacks/application-stack.ts
import { MyDatabase } from '@my-scope/common-constructs';
const db = new MyDatabase(this, 'Db', {
...
enableKeyRotation: false,
});
engine = mysql

MySQL: API Gateway ストリーミングモード

Section titled “MySQL: API Gateway ストリーミングモード”

Aurora MySQL を API Gateway ストリーミングレスポンス(例:tRPC の httpBatchStreamLink)と併用する場合、Prisma MySQL クライアントはクエリ完了後も Node.js イベントループを保持し、Lambda がストリームをフラッシュしてリクエストを終了するのを妨げます。

これを回避するには、各クエリ後に finally ブロックでクライアントを明示的に切断し、イベントループが終了してストリーミングレスポンスが完了できるようにします。

オプション 1: per-procedure

export const listExampleTable = publicProcedure
.output(z.array(ExampleTableSchema))
.query(async () => {
const prisma = await getPrisma();
try {
return await prisma.exampleTable.findMany();
} finally {
await prisma.$disconnect();
}
});

オプション 2: tRPC middleware

ミドルウェアパターンを使用している場合は、ミドルウェアに $disconnect() 呼び出しを追加して、それに基づいて構築されたすべてのプロシージャが自動的にカバーされるようにします:

packages/api/src/middleware/db.ts
import { getPrisma } from '@my-scope/db';
import { initTRPC } from '@trpc/server';
export interface IDbContext {
db: Awaited<ReturnType<typeof getPrisma>>;
}
export const createDbPlugin = () => {
const t = initTRPC.context<IDbContext>().create();
return t.procedure.use(async (opts) => {
const db = await getPrisma();
try {
return await opts.next({
ctx: {
...opts.ctx,
db,
},
});
} finally {
await db.$disconnect();
}
});
};

RDS IAM 認証トークンは 15 分後に期限切れになります。MySQL Prisma クライアントは、getPrisma() が呼び出された時点で IAM トークンを静的な値としてキャプチャします。既存の開いている接続は影響を受けませんが、トークンの期限が切れた後に新しい接続を確立する必要がある場合、認証は失敗します。PostgreSQL アダプターは、プールが新しい接続を開くたびにトークンを動的に更新することでこれを回避しますが、MySQL アダプターには同等のメカニズムがありません。

バッチジョブやデータマイグレーションなどの長時間実行タスクの場合、操作全体に対して一度ではなく、各作業単位の開始時に getPrisma() を呼び出します。getPrisma() は MySQL に対して常に新しいクライアントを作成し、新しい IAM トークンを取得するため、各接続が有効なトークンで認証されることが保証されます。

connection ジェネレーターを使用して、このプロジェクトをワークスペース内の他のプロジェクトと統合します。このプロジェクトに関連する接続は以下の通りです:

tRPCAmazon Aurora
tRPC API to Relational DatabasetRPC API を Aurora リレーショナルデータベースに接続する
SmithyAmazon Aurora
Smithy API to Relational DatabaseSmithy API を Aurora リレーショナルデータベースに接続する
Strands AgentsTypeScriptAmazon Aurora
TypeScript Agent to Relational DatabaseTypeScript Agent を Aurora リレーショナルデータベースに接続する
Model Context ProtocolAmazon Aurora
MCP Server to Relational DatabaseTypeScript MCP Server を Aurora リレーショナルデータベースに接続する