リレーショナルデータベース
このジェネレーターは、Amazon Aurora(PostgreSQLまたはMySQL)とPrisma ORMを基盤とする新しいリレーショナルデータベースプロジェクトを作成します。AWS CDKまたはTerraformを使用してデータベースをプロビジョニングおよび管理するために必要なアプリケーションコードとインフラストラクチャを生成し、宣言的なスキーマ定義、自動マイグレーションデプロイ、型安全なORMクライアントを提供します。
リレーショナルデータベースの生成
Section titled “リレーショナルデータベースの生成”新しいリレーショナルデータベースプロジェクトは、2つの方法で生成できます:
- インストール Nx Console VSCode Plugin まだインストールしていない場合
- VSCodeでNxコンソールを開く
- クリック
Generate (UI)"Common Nx Commands"セクションで - 検索
@aws/nx-plugin - ts#rdb - 必須パラメータを入力
- クリック
Generate
pnpm nx g @aws/nx-plugin:ts#rdbyarn nx g @aws/nx-plugin:ts#rdbnpx nx g @aws/nx-plugin:ts#rdbbunx nx g @aws/nx-plugin:ts#rdb| パラメータ | 型 | デフォルト | 説明 |
|---|---|---|---|
| name 必須 | string | - | 生成するデータベースプロジェクトの名前 |
| directory | string | packages | アプリケーションを保存するディレクトリ |
| subDirectory | string | - | プロジェクトが配置されるサブディレクトリ。デフォルトではプロジェクト名になります。 |
| service 必須 | string | Aurora | プロビジョニングするリレーショナルデータベースサービス |
| engine 必須 | string | PostgreSQL | 選択したサービスで使用するデータベースエンジン |
| databaseUser | string | dbadmin | データベース管理者のユーザー名。デフォルトは 'dbadmin' です。 |
| databaseName | string | - | 初期データベース名。デフォルトではプロジェクト名になります。 |
| ormFramework 必須 | string | Prisma | 生成されるプロジェクトで使用するORMフレームワーク |
| iacProvider | string | Inherit | 優先するIaCプロバイダー。デフォルトでは初期選択から継承されます |
ジェネレーターの出力
Section titled “ジェネレーターの出力”ジェネレーターは、<directory>/<name>ディレクトリに以下のプロジェクト構造を作成します:
Directoryprisma
Directorymodels
- example.prisma サンプルモデル定義
- schema.prisma メインPrismaスキーマ(モデルを参照)
Directoryscripts
- docker-pull.ts ローカル開発用のデータベースDockerイメージをプル
- docker-start.ts ローカルデータベースコンテナを起動
- wait-for-db.ts ローカルデータベースの準備完了を待機
Directorysrc
- index.ts プロジェクトのエントリーポイント
- constants.ts ローカル開発接続の詳細とランタイム設定キー
- prisma.ts Prismaランタイムクライアントラッパー
- utils.ts ランタイム設定とシークレットヘルパー
- create-db-user-handler.ts デプロイ時にアプリケーションデータベースユーザーを作成するために使用されるLambdaハンドラー
- migration-handler.ts デプロイ時にデータベースマイグレーションを実行するために使用されるLambdaハンドラー
- .gitignore 生成されたPrismaクライアント出力を含むGit ignoreエントリ
- Dockerfile マイグレーションハンドラーのコンテナイメージ定義
- project.json プロジェクト設定とビルドターゲット
- prisma.config.ts Prisma CLIの設定
インフラストラクチャ
Section titled “インフラストラクチャ”このジェネレータは選択した iacProvider に基づいてInfrastructure as Codeを生成するため、packages/common に関連するCDKコンストラクトまたはTerraformモジュールを含むプロジェクトを作成します。
共通のInfrastructure as Codeプロジェクトは以下の構造を持ちます:
Directorypackages/common/constructs
Directorysrc
Directoryapp/ プロジェクト/ジェネレータ固有のインフラストラクチャ用コンストラクト
- …
Directorycore/
app内のコンストラクトで再利用される汎用コンストラクト- …
- index.ts
appからコンストラクトをエクスポートするエントリーポイント
- project.json プロジェクトのビルドターゲットと設定
Directorypackages/common/terraform
Directorysrc
Directoryapp/ プロジェクト/ジェネレータ固有のインフラストラクチャ用Terraformモジュール
- …
Directorycore/
app内のモジュールで再利用される汎用モジュール- …
- project.json プロジェクトのビルドターゲットと設定
Directorypackages/common/constructs/src
Directoryapp
Directorydbs
- <name>.ts データベース固有のインフラストラクチャ
Directorycore
Directoryrdb
- aurora.ts 汎用Auroraデータベースコンストラクト
Directorypackages/common/terraform/src
Directoryapp
Directorydbs
Directory<name>
- <name>.tf データベース固有のモジュール
Directorycore
Directoryrdb
Directoryaurora
- aurora.tf 汎用Auroraモジュール
ローカル開発
Section titled “ローカル開発”データモデリング
Section titled “データモデリング”生成されたプロジェクトは、データベーススキーマの定義と型安全なクライアントの生成にPrisma ORMを使用します。ワークフローはモデルファーストです: データベースプロジェクトのprisma/models/ディレクトリ配下にPrismaモデルファイルを追加または更新し、それらのモデル変更からマイグレーションを生成します。
Userモデルの例:
model User { id Int @id @default(autoincrement()) firstName String lastName String}詳細については、公式のPrismaデータモデリングガイドを参照してください。
データベースクライアントの生成
Section titled “データベースクライアントの生成”ジェネレーターは、プロジェクトをビルドするたびに型安全なTypeScript Prismaクライアントを作成するようにgenerateターゲットを自動的に構成します。クライアントはgenerated/prismaに書き込まれます(.gitignoreに追加されます)。
また、いつでも手動でクライアントを生成できます:
pnpm nx generate <your-db-project-name>yarn nx generate <your-db-project-name>npx nx generate <your-db-project-name>bunx nx generate <your-db-project-name>ワークスペースルートからprismaターゲットを使用してPrisma CLIコマンドを実行します:
pnpm nx run <project>:prisma generateyarn nx run <project>:prisma generatenpx nx run <project>:prisma generatebunx nx run <project>:prisma generatesrc/prisma.tsのランタイムラッパーは以下をエクスポートします:
DB_PACKAGE_NAME- AWS AppConfigのdatabaseランタイム設定名前空間で使用されるキーgetPrisma()- AWS AppConfigからデータベース接続設定を読み込み、IAM認証を使用してPrismaクライアントを作成します
クライアントは自動的に以下を行います:
RUNTIME_CONFIG_APP_ID環境変数を使用してAWS AppConfigからデータベース設定を取得- IAM認証用にAWS RDS Signerを介して一時的な認証トークンを生成
- 証明書検証を使用してSSL/TLS接続を管理
- 永続的なデータベース接続プールを通じて接続プーリングを処理
マイグレーションの作成
Section titled “マイグレーションの作成”prisma/models/配下にモデルを追加または更新した後、migrate devを使用してマイグレーションファイルを生成し、同時にローカルデータベースに適用します。
生成されたprismaターゲットは、実行前にDocker経由でローカルデータベースを自動的に起動します:
pnpm nx run <project>:prisma migrate devyarn nx run <project>:prisma migrate devnpx nx run <project>:prisma migrate devbunx nx run <project>:prisma migrate devローカルデータベースに適用せずにマイグレーションファイルのみを生成したい場合は、--create-onlyを追加します:
pnpm nx run <project>:prisma migrate dev --create-onlyyarn nx run <project>:prisma migrate dev --create-onlynpx nx run <project>:prisma migrate dev --create-onlybunx 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を使用してそれらの既存のマイグレーションをローカルデータベースに適用します。
pnpm nx run <project>:prisma migrate deployyarn nx run <project>:prisma migrate deploynpx nx run <project>:prisma migrate deploybunx nx run <project>:prisma migrate deployこのローカル開発フローでは、migrate deployはマイグレーションファイルをローカルデータベースに適用します。データベースをAWSにデプロイするわけではありません。
Prismaコマンドの実行
Section titled “Prismaコマンドの実行”生成されたprismaターゲットはPrisma CLIを公開しているため、ローカルデータベースに対してPrismaがサポートする任意のコマンドを実行できます。利用可能なコマンドについては、Prisma CLIリファレンスを参照してください。
pnpm nx run <project>:prisma <prisma-command>yarn nx run <project>:prisma <prisma-command>npx nx run <project>:prisma <prisma-command>bunx nx run <project>:prisma <prisma-command>Prisma Studio
Section titled “Prisma Studio”Prisma Studioは、ローカルデータベース用のビジュアルエディタです。テーブルの閲覧、レコードの検査と編集、データのフィルタリング、リレーションのフォロー、組み込みSQLコンソールを介した生SQLの実行に使用できます。マイグレーションの検証や開発中のテストデータのシードに便利です。次のコマンドで起動します:
pnpm nx run <project>:prisma studioyarn nx run <project>:prisma studionpx nx run <project>:prisma studiobunx nx run <project>:prisma studiotRPC APIからの接続
Section titled “tRPC APIからの接続”このセクションでは、tRPC APIからデータベースに接続する方法を説明していますが、他のTypeScriptプロジェクトでの使用の参考にもなります。
ハンドラーでのPrismaクライアントの使用
Section titled “ハンドラーでのPrismaクライアントの使用”データベースパッケージからgetPrismaをインポートし、ハンドラー内で呼び出して型安全なPrismaクライアントを取得します:
import { getPrisma } from ':my-scope/db';import { publicProcedure } from '../init.js';import { ListUsersOutputSchema } from '../schema/index.js';
export const listUsers = publicProcedure .output(ListUsersOutputSchema) .query(async () => { const prisma = await getPrisma(); return prisma.user.findMany({ orderBy: { id: 'asc' } }); });getPrisma()は遅延初期化されたキャッシュされたクライアントを返します。同じLambda実行コンテキスト内での後続の呼び出しは、新しい接続を開くのではなく、既存の接続プールを再利用します。
Prismaクライアントは、prisma/models/スキーマから派生した完全に型付けされたモデルを公開し、データベースからAPIレスポンスまでのエンドツーエンドの型安全性を提供します。
ミドルウェアを介したPrismaクライアントの注入
Section titled “ミドルウェアを介したPrismaクライアントの注入”すべてのプロシージャでgetPrisma()を呼び出すのではなく、ミドルウェアで一度解決してtRPCコンテキストにアタッチすることで、すべての下流プロシージャが直接アクセスできるようにすることもできます。
まず、生成されたミドルウェアと同じパターンに従って、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(); return opts.next({ ctx: { ...opts.ctx, db, }, }); });};次に、tRPCの初期化でベースプロシージャに連結します:
import { createDbPlugin } from './middleware/db.js';
export const dbProcedure = publicProcedure.concat(createDbPlugin());dbProcedure上に構築されたプロシージャは、getPrisma()をインポートまたは呼び出す必要なく、コンテキストを通じてdbを受け取ります:
import { dbProcedure } from '../init.js';import { ListUsersOutputSchema } from '../schema/index.js';
export const listUsers = dbProcedure .output(ListUsersOutputSchema) .query(async ({ ctx: { db } }) => { return db.user.findMany({ orderBy: { id: 'asc' } }); });データベースのデプロイ
Section titled “データベースのデプロイ”リレーショナルデータベースジェネレーターは、選択したiacProviderに基づいてCDKまたはTerraformのインフラストラクチャを作成します。
CDKコンストラクトはcommon/constructsに作成されます。使用例:
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認証が有効化され、アプリケーションデータベースに対する完全な権限を持ちます
Terraformモジュールはcommon/terraformに作成されます。使用例:
module "my_database" { source = "../../common/terraform/src/app/dbs/my-database"
vpc_id = module.vpc.vpc_id database_subnet_ids = module.vpc.private_isolated_subnet_ids lambda_subnet_ids = module.vpc.private_subnet_ids
tags = local.common_tags}これにより、RDS Proxy、管理者認証情報、create-db-user Lambda、ランタイム設定の登録、マイグレーションLambda、コンテナレジストリリソースを備えたAuroraクラスターがプロビジョニングされます。
生成されたインフラストラクチャは、2つのデータベースユーザーを作成します:
- 管理者ユーザー - クラスターのプロビジョニング時に作成され、認証情報はAWS Secrets Managerに保存されます
- アプリケーションユーザー - Lambda関数を介して作成され、IAM認証が有効化され、アプリケーションデータベースに対する完全な権限を持ちます
アプリケーションユーザーは、ランダムな名前とIAM認証で自動的に作成されます。getPrisma()は、短期間有効なRDSトークンを使用してこのユーザーとして認証するように既に構成されているため、アプリケーションコードがデータベースパスワードを処理することはありません。
VPCには、パブリックサブネット、エグレスを持つプライベートサブネット、プライベート分離サブネットを含める必要があります。データベースはプライベート分離サブネットで実行でき、API Lambda関数はエグレスを持つプライベートサブネットで実行して、AppConfigなどのAWSサービスに到達できるようにする必要があります。
const vpc = new Vpc(this, 'Vpc', { subnetConfiguration: [ { name: 'public', subnetType: SubnetType.PUBLIC, }, { name: 'private_with_egress', subnetType: SubnetType.PRIVATE_WITH_EGRESS, }, { name: 'private_isolated', subnetType: SubnetType.PRIVATE_ISOLATED, }, ],});module "vpc" { source = "terraform-aws-modules/vpc/aws" version = "~> 6.0"
name = "app" ... public_subnet_names = ["public"] private_subnet_names = ["private_with_egress"] intra_subnet_names = ["private_isolated"]
enable_nat_gateway = true single_nat_gateway = true}APIのデータベースへの接続
Section titled “APIのデータベースへの接続”アプリケーションスタックで、APIをデータベースと同じVPCにデプロイし、allowDefaultPortFromとgrantConnectを呼び出して、各Lambdaハンドラーへのネットワークパスを開き、IAM rds-db:connect権限を付与します:
import { MyDatabase } from ':my-scope/common-constructs';
const db = new MyDatabase(this, 'Db', { vpc, ... });
const api = new Api(this, 'Api', { integrations: Api.defaultIntegrations(this) .withDefaultOptions({ vpc, vpcSubnets: { subnetType: SubnetType.PRIVATE_WITH_EGRESS }, }) .build(),});
Object.entries(api.integrations).forEach(([operation, integration]) => { db.allowDefaultPortFrom(integration.handler, `Allow ${operation} to connect to the database`); db.grantConnect(integration.handler);});API Lambda関数をエグレスを持つプライベートサブネット(推奨)またはパブリックサブネットにデプロイし、プライベート分離サブネットにはデプロイしないでください。実行時に、getPrisma()はAWS AppConfigからデータベース接続の詳細を取得しますが、これはパブリックAWSサービスエンドポイントです。プライベート分離サブネット内のLambda関数には、アウトバウンドインターネットアクセスがなく、AppConfigに到達できません。エグレスを持つプライベートサブネットは、パブリックサブネットに配置されたNAT Gatewayを介してアウトバウンドトラフィックをルーティングします。
データベースモジュールの出力をコンピュートモジュールに渡して、データベースに到達し、そのランタイム設定を読み取れるようにします:
module "my_database" { source = "../../common/terraform/src/app/dbs/my-database" vpc_id = module.vpc.vpc_id database_subnet_ids = module.vpc.private_isolated_subnet_ids lambda_subnet_ids = module.vpc.private_subnet_ids}
module "api" { source = "..." vpc_id = module.vpc.vpc_id private_subnet_ids = module.vpc.private_subnet_ids
# APIがAppConfigからランタイム設定を読み取れるようにする appconfig_application_id = module.my_database.appconfig_application_id
# アプリケーションデータベースユーザーにrds-db:connectを付与 database_cluster_resource_id = module.my_database.cluster_resource_id database_runtime_user = module.my_database.database_runtime_user
# データベースポートへのネットワークアクセスを許可 database_security_group_id = module.my_database.security_group_id database_port = module.my_database.cluster_port
environment_variables = { RUNTIME_CONFIG_APP_ID = module.my_database.appconfig_application_id }}API Lambda関数をエグレスを持つプライベートサブネット(推奨)またはパブリックサブネットにデプロイし、プライベート分離サブネットにはデプロイしないでください。実行時に、getPrisma()はAWS AppConfigからデータベース接続の詳細を取得しますが、これはパブリックAWSサービスエンドポイントです。プライベート分離サブネット内のLambda関数には、アウトバウンドインターネットアクセスがなく、AppConfigに到達できません。エグレスを持つプライベートサブネットは、パブリックサブネットを必要とするNAT Gatewayを介してアウトバウンドトラフィックをルーティングします。
API Lambdaロールがarn:aws:rds-db:<region>:<account>:dbuser:<cluster_resource_id>/<database_runtime_user>に対するrds-db:connectとAppConfig読み取り権限を持ち、APIのセキュリティグループがデータベースポートでデータベースセキュリティグループに到達でき、Lambda環境にRUNTIME_CONFIG_APP_IDが含まれていることを確認してください。
RDS Proxyの設定
Section titled “RDS Proxyの設定”生成されたインフラストラクチャには、デフォルトでRDS Proxyが含まれており、アプリケーションとAuroraクラスターの間に配置されます。RDS Proxyは、いくつかの利点を提供します:
- 接続プーリング - アプリケーションインスタンス間で共有できるデータベース接続のプールを維持し、新しい接続を確立するオーバーヘッドを削減します
- 接続の回復力 - Auroraインスタンスの交換やメンテナンス中のフェイルオーバーと再接続を自動的に処理します
- IAM認証 - IAMベースのデータベース認証をサポートし、アプリケーションコードでデータベース認証情報を管理する必要がなくなります
- セキュリティの向上 - すべての接続にTLS暗号化を強制します
RDS Proxyの無効化
Section titled “RDS Proxyの無効化”RDS Proxyは次のように無効にできます:
import { MyDatabase } from ':my-scope/common-constructs';
const db = new MyDatabase(this, 'Db', { ... enableRdsProxy: false,});RDS Proxyが無効になっている場合、アプリケーションはAuroraクラスターエンドポイントに直接接続します。
Node.js 20以降のLambdaランタイムからAuroraクラスターに直接接続する場合は、Amazon RDS CAバンドルを読み込むようにLambda関数を構成します:
const api = new Api(this, 'Api', { integrations: Api.defaultIntegrations(this) .withDefaultOptions({ environment: { NODE_EXTRA_CA_CERTS: '/var/runtime/ca-cert.pem', }, }) .build(),});デフォルトでは、RDS Proxyが有効になっています。生成されたランタイムクライアント(getPrisma())は、プロキシエンドポイントを介して自動的に接続します。必要に応じて無効にできます:
module "my_database" { source = "../../common/terraform/src/app/dbs/my-database" ... enable_rds_proxy = false}RDS Proxyが無効になっている場合、アプリケーションはAuroraクラスターエンドポイントに直接接続します。
Node.js 20以降のLambdaランタイムからAuroraクラスターに直接接続する場合は、Amazon RDS CAバンドルを読み込むようにLambda関数を構成します:
module "api" { source = "..." ...
environment_variables = { NODE_EXTRA_CA_CERTS = "/var/runtime/ca-cert.pem" }}詳細については、AWS LambdaのAmazon RDS接続のSSL/TLS要件およびAmazon RDS ProxyのTLSドキュメントを参照してください。RDS Proxyを使用する場合、Lambda関数でRDS CAバンドルを構成する必要はありません。
生成されたインフラストラクチャは、ワークロードの要件に合わせてカスタマイズできます。以下の例は、利用可能な一般的なカスタマイズオプションのいくつかを示しています。
クラスターインスタンス
Section titled “クラスターインスタンス”Auroraクラスターのwriterおよびreaderインスタンスを構成します。
import { MyDatabase } from ':my-scope/common-constructs';
const db = new MyDatabase(this, 'Db', { ... writer: ClusterInstance.serverlessV2('writer'), readers: [ClusterInstance.serverlessV2('reader')],});module "my_database" { source = "../../common/terraform/src/app/dbs/my-database" ... instance_count = 2 # 1 writer + 1 reader}サーバーレスキャパシティ
Section titled “サーバーレスキャパシティ”ワークロードに合わせてAurora Serverless v2のスケーリング制限を制御します。
import { MyDatabase } from ':my-scope/common-constructs';
const db = new MyDatabase(this, 'Db', { ... serverlessV2MinCapacity: 0.5, serverlessV2MaxCapacity: 8,});module "my_database" { source = "../../common/terraform/src/app/dbs/my-database" ... serverless_min_capacity = 0.5 serverless_max_capacity = 8}エンジンバージョン
Section titled “エンジンバージョン”特定のAuroraエンジンバージョンを固定します。
デフォルトでは、生成されたローカルDockerデータベースイメージは、デフォルトのAuroraエンジンバージョンと一致します。Auroraエンジンバージョンを変更する場合は、最大限の互換性を得るために、一致するローカルDockerデータベースバージョンも使用することをお勧めします。対応するコミュニティデータベースバージョンを特定するには、Aurora PostgreSQLバージョンおよびAurora MySQLバージョン3の更新のAWSリリースノートを参照してください。
ローカルデータベースイメージは、生成されたデータベースプロジェクトのproject.jsonのserve-localターゲットで構成されています。エンジンバージョンを変更する際は、scripts/docker-start.tsに渡されるイメージ引数を更新してください。
import { MyDatabase } from ':my-scope/common-constructs';
const db = new MyDatabase(this, 'Db', { ... engineVersion: AuroraPostgresEngineVersion.VER_17_7,});module "my_database" { source = "../../common/terraform/src/app/dbs/my-database" ... engine_version = "17.7"}import { MyDatabase } from ':my-scope/common-constructs';
const db = new MyDatabase(this, 'Db', { ... engineVersion: AuroraMysqlEngineVersion.VER_3_12_0,});module "my_database" { source = "../../common/terraform/src/app/dbs/my-database" ... engine_version = "8.0.mysql_aurora.3.12.0"}削除保護は、デフォルトで有効になっており(CDKではdeletionProtection: true、Terraformではdeletion_protection = true)、Auroraクラスターを誤って削除から保護します。
削除保護の無効化
Section titled “削除保護の無効化”データベースの削除が予想される環境(短期間の開発環境やプレビュースタックなど)では、削除保護を無効にできます。
import { MyDatabase } from ':my-scope/common-constructs';
const db = new MyDatabase(this, 'Db', { ... deletionProtection: false,});module "my_database" { source = "../../common/terraform/src/app/dbs/my-database" ... deletion_protection = false}削除ポリシー
Section titled “削除ポリシー”CDKコンストラクトは、デフォルトでAuroraクラスターを保持します(removalPolicy: RemovalPolicy.RETAIN)。CDKスタックの削除時にクラスターをスナップショットまたは破棄したい場合は、これを変更してください。
RemovalPolicy.DESTROYを使用する場合、クラスターを削除する前に削除保護も無効にする必要があります。
import { RemovalPolicy } from 'aws-cdk-lib';import { MyDatabase } from ':my-scope/common-constructs';
const db = new MyDatabase(this, 'Db', { ... removalPolicy: RemovalPolicy.SNAPSHOT,});スタックと共にデータベースを削除する必要がある一時的な環境の場合:
import { RemovalPolicy } from 'aws-cdk-lib';import { MyDatabase } from ':my-scope/common-constructs';
const db = new MyDatabase(this, 'Db', { ... deletionProtection: false, removalPolicy: RemovalPolicy.DESTROY,});TerraformはCDKの削除ポリシーを使用しません。デフォルトでは、モジュールは削除時に最終スナップショットを作成します(skip_final_snapshot = false)。一時的な環境で最終スナップショットをスキップする場合:
module "my_database" { source = "../../common/terraform/src/app/dbs/my-database" ... deletion_protection = false skip_final_snapshot = true}暗号化キーのローテーション
Section titled “暗号化キーのローテーション”Auroraクラスターとその認証情報シークレットの暗号化に使用されるKMSキーは、デフォルトで自動キーローテーションが有効になっています。セキュリティポリシーが外部でローテーションを管理している場合は、無効にしてください。
import { MyDatabase } from ':my-scope/common-constructs';
const db = new MyDatabase(this, 'Db', { ... enableKeyRotation: false,});module "my_database" { source = "../../common/terraform/src/app/dbs/my-database" ... enable_key_rotation = false}MySQL: API Gatewayストリーミングモード
Section titled “MySQL: API Gatewayストリーミングモード”Aurora MySQLをAPI Gatewayストリーミングレスポンス(例:tRPCのhttpBatchStreamLink)と併用する場合、Prisma MySQLクライアントはクエリ完了後もNode.jsイベントループを保持し、Lambdaがストリームをフラッシュしてリクエストを終了できなくなります。
この問題を回避するには、各クエリ後にfinallyブロックでクライアントを明示的に切断し、イベントループが終了してストリーミングレスポンスが完了できるようにします。
オプション1: プロシージャごと
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ミドルウェア
ミドルウェアパターンを使用している場合は、ミドルウェアに$disconnect()呼び出しを追加して、それに基づいて構築されたすべてのプロシージャが自動的にカバーされるようにします:
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(); } });};MySQL: IAMトークンの有効期限
Section titled “MySQL: IAMトークンの有効期限”RDS IAM認証トークンは15分後に期限切れになります。MySQL Prismaクライアントは、getPrisma()が呼び出された時点でIAMトークンを静的な値としてキャプチャします。既存の開いている接続は影響を受けませんが、トークンの有効期限が切れた後に新しい接続を確立する必要がある場合、認証は失敗します。PostgreSQLアダプターは、プールが新しい接続を開くたびにトークンを動的に更新することでこれを回避しますが、MySQLアダプターには同等のメカニズムがありません。
バッチジョブやデータ移行などの長時間実行タスクの場合は、操作全体に対して一度ではなく、各作業単位の開始時にgetPrisma()を呼び出してください。getPrisma()はMySQLに対して常に新しいクライアントを作成し、新しいIAMトークンを取得するため、各接続が有効なトークンで認証されることが保証されます。