Base de données relationnelle
Ce générateur crée un nouveau projet de base de données relationnelle basé sur Amazon Aurora (PostgreSQL ou MySQL) et Prisma ORM. Il génère le code d’application et l’infrastructure nécessaires pour provisionner et gérer une base de données en utilisant AWS CDK ou Terraform, avec une définition de schéma déclarative, un déploiement automatique des migrations et un client ORM type-safe.
Utilisation
Section intitulée « Utilisation »Générer une base de données relationnelle
Section intitulée « Générer une base de données relationnelle »Vous pouvez générer un nouveau projet de base de données relationnelle de deux manières :
- Installez le Nx Console VSCode Plugin si ce n'est pas déjà fait
- Ouvrez la console Nx dans VSCode
- Cliquez sur
Generate (UI)dans la section "Common Nx Commands" - Recherchez
@aws/nx-plugin - ts#rdb - Remplissez les paramètres requis
- Cliquez sur
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#rdbVous pouvez également effectuer une simulation pour voir quels fichiers seraient modifiés
pnpm nx g @aws/nx-plugin:ts#rdb --dry-runyarn nx g @aws/nx-plugin:ts#rdb --dry-runnpx nx g @aws/nx-plugin:ts#rdb --dry-runbunx nx g @aws/nx-plugin:ts#rdb --dry-run| Paramètre | Type | Par défaut | Description |
|---|---|---|---|
| name Requis | string | - | Nom du projet de base de données à générer |
| directory | string | packages | Le répertoire dans lequel stocker l'application. |
| subDirectory | string | - | Le sous-répertoire dans lequel le projet est placé. Par défaut, il s'agit du nom du projet. |
| service Requis | string | Aurora | Service de base de données relationnelle à provisionner. |
| engine Requis | string | PostgreSQL | Moteur de base de données à utiliser avec le service sélectionné. |
| databaseUser | string | dbadmin | Nom d'utilisateur administrateur de la base de données. Par défaut 'dbadmin'. |
| databaseName | string | - | Nom initial de la base de données. Par défaut, le nom du projet. |
| ormFramework Requis | string | Prisma | Framework ORM à utiliser pour le projet généré. |
| iacProvider | string | Inherit | Le fournisseur IaC préféré. Par défaut, celui-ci est hérité de votre sélection initiale. |
Sortie du générateur
Section intitulée « Sortie du générateur »Le générateur créera la structure de projet suivante dans le répertoire <directory>/<name> :
Répertoireprisma
Répertoiremodels
- example.prisma Définition de modèle d’exemple
- schema.prisma Schéma Prisma principal (référence les modèles)
Répertoirescripts
- docker-pull.ts Télécharge l’image Docker de la base de données pour le développement local
- docker-start.ts Démarre un conteneur de base de données local
- wait-for-db.ts Attend que la base de données locale soit prête
Répertoiresrc
- index.ts Point d’entrée du projet
- constants.ts Détails de connexion pour le développement local et clé de configuration d’exécution
- prisma.ts Wrapper du client Prisma d’exécution
- utils.ts Helpers de configuration d’exécution et de secrets
- create-db-user-handler.ts Gestionnaire Lambda utilisé pour créer l’utilisateur de base de données d’application pendant le déploiement
- migration-handler.ts Gestionnaire Lambda utilisé pour exécuter les migrations de base de données pendant le déploiement
- .gitignore Entrées d’ignorance Git incluant la sortie du client Prisma généré
- Dockerfile Définition de l’image conteneur pour le gestionnaire de migration
- project.json Configuration du projet et cibles de build
- prisma.config.ts Configuration pour Prisma CLI
Infrastructure
Section intitulée « Infrastructure »Ce générateur fournit de l’infrastructure as code basée sur votre iacProvider choisi. Il créera un projet dans packages/common qui inclut les constructions CDK ou modules Terraform pertinents.
Le projet commun d’infrastructure as code est structuré comme suit :
Répertoirepackages/common/constructs
Répertoiresrc
Répertoireapp/ Constructions pour l’infrastructure spécifique à un projet/générateur
- …
Répertoirecore/ Constructions génériques réutilisées par celles dans
app- …
- index.ts Point d’entrée exportant les constructions depuis
app
- project.json Cibles de build et configuration du projet
Répertoirepackages/common/terraform
Répertoiresrc
Répertoireapp/ Modules Terraform pour l’infrastructure spécifique à un projet/générateur
- …
Répertoirecore/ Modules génériques réutilisés par ceux dans
app- …
- project.json Cibles de build et configuration du projet
Répertoirepackages/common/constructs/src
Répertoireapp
Répertoiredbs
- <name>.ts Infrastructure spécifique à votre base de données
Répertoirecore
Répertoirerdb
- aurora.ts Construction de base de données Aurora générique
Répertoirepackages/common/terraform/src
Répertoireapp
Répertoiredbs
Répertoire<name>
- <name>.tf Module spécifique à votre base de données
Répertoirecore
Répertoirerdb
Répertoireaurora
- aurora.tf Module Aurora générique
Développement local
Section intitulée « Développement local »Modélisation des données
Section intitulée « Modélisation des données »Le projet généré utilise Prisma ORM pour définir votre schéma de base de données et générer un client type-safe. Le flux de travail est axé sur le modèle : ajoutez ou mettez à jour les fichiers de modèle Prisma dans le répertoire prisma/models/ de votre projet de base de données, puis générez une migration à partir de ces modifications de modèle.
Exemple de modèle User :
model User { id Int @id @default(autoincrement()) firstName String lastName String}Pour plus de détails, consultez le guide officiel sur la modélisation des données avec Prisma.
Générer le client de base de données
Section intitulée « Générer le client de base de données »Le générateur configure automatiquement la cible generate pour créer un client Prisma TypeScript type-safe chaque fois que vous construisez le projet. Le client est écrit dans generated/prisma (ajouté à .gitignore).
Vous pouvez également générer manuellement le client à tout moment :
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>Utilisez la cible prisma pour exécuter les commandes CLI Prisma depuis la racine de l’espace de travail :
pnpm nx run <project>:prisma generateyarn nx run <project>:prisma generatenpx nx run <project>:prisma generatebunx nx run <project>:prisma generateLe wrapper d’exécution dans src/prisma.ts exporte :
DB_PACKAGE_NAME- la clé utilisée sous l’espace de noms de configuration d’exécutiondatabasedans AWS AppConfiggetPrisma()- charge les paramètres de connexion à la base de données depuis AWS AppConfig et crée un client Prisma utilisant l’authentification IAM
Le client automatiquement :
- Récupère la configuration de la base de données depuis AWS AppConfig en utilisant la variable d’environnement
RUNTIME_CONFIG_APP_ID - Génère des jetons d’authentification temporaires via AWS RDS Signer pour l’authentification IAM
- Gère les connexions SSL/TLS avec validation de certificat
- Gère le pooling de connexions via des pools de connexions de base de données persistants
Créer des migrations
Section intitulée « Créer des migrations »Après avoir ajouté ou mis à jour des modèles sous prisma/models/, utilisez migrate dev pour générer les fichiers de migration et les appliquer à votre base de données locale en même temps.
La cible prisma générée démarre automatiquement une base de données locale via Docker avant l’exécution :
pnpm nx run <project>:prisma migrate devyarn nx run <project>:prisma migrate devnpx nx run <project>:prisma migrate devbunx nx run <project>:prisma migrate devSi vous souhaitez uniquement générer les fichiers de migration sans les appliquer à la base de données locale, ajoutez --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-onlyCela génère un nouveau dossier de migration dans prisma/migrations chaque fois que votre schéma change :
Répertoireprisma
Répertoiremigrations
Répertoire20260405013911_initial_migrations
- migration.sql
- migration_lock.toml
- schema.prisma
Lorsque vous déployez la stack AWS, l’infrastructure générée applique automatiquement les migrations générées à la base de données déployée.
Appliquer les migrations existantes
Section intitulée « Appliquer les migrations existantes »Lorsque vous récupérez des fichiers de migration créés par d’autres développeurs, utilisez migrate deploy pour appliquer ces migrations existantes à votre base de données locale.
pnpm nx run <project>:prisma migrate deployyarn nx run <project>:prisma migrate deploynpx nx run <project>:prisma migrate deploybunx nx run <project>:prisma migrate deployDans ce flux de développement local, migrate deploy applique les fichiers de migration à votre base de données locale ; il ne déploie pas la base de données sur AWS.
Exécuter les commandes Prisma
Section intitulée « Exécuter les commandes Prisma »La cible prisma générée expose la CLI Prisma, vous pouvez donc l’utiliser pour exécuter n’importe quelle commande prise en charge par Prisma contre la base de données locale. Consultez la référence CLI Prisma pour les commandes disponibles.
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 intitulée « Prisma Studio »Prisma Studio est un éditeur visuel pour votre base de données locale. Utilisez-le pour parcourir les tables, inspecter et modifier les enregistrements, filtrer les données, suivre les relations et exécuter du SQL brut via la console SQL intégrée. Il est utile pour vérifier les migrations et alimenter les données de test pendant le développement. Lancez-le avec :
pnpm nx run <project>:prisma studioyarn nx run <project>:prisma studionpx nx run <project>:prisma studiobunx nx run <project>:prisma studioConnexion depuis une API tRPC
Section intitulée « Connexion depuis une API tRPC »Bien que cette section décrive comment se connecter à votre base de données depuis une API tRPC, elle sert également de référence pour une utilisation dans tout autre projet TypeScript.
Utiliser le client Prisma dans les gestionnaires
Section intitulée « Utiliser le client Prisma dans les gestionnaires »Importez getPrisma depuis votre package de base de données et appelez-le à l’intérieur de votre gestionnaire pour obtenir un client Prisma type-safe :
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() retourne un client initialisé de manière paresseuse et mis en cache. Les appels suivants dans le même contexte d’exécution Lambda réutilisent le pool de connexions existant plutôt que d’en ouvrir un nouveau.
Le client Prisma expose des modèles entièrement typés dérivés de votre schéma prisma/models/, vous offrant une sécurité de type de bout en bout depuis la base de données jusqu’à votre réponse API.
Injecter le client Prisma via un middleware
Section intitulée « Injecter le client Prisma via un middleware »Plutôt que d’appeler getPrisma() dans chaque procédure, vous pouvez également le résoudre une fois dans un middleware et l’attacher au contexte tRPC afin que toutes les procédures en aval puissent y accéder directement.
Tout d’abord, définissez le plugin dans src/middleware/db.ts en suivant le même modèle que le middleware généré :
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, }, }); });};Ensuite, concaténez-le à une procédure de base dans votre initialisation tRPC :
import { createDbPlugin } from './middleware/db.js';
export const dbProcedure = publicProcedure.concat(createDbPlugin());Les procédures construites sur dbProcedure reçoivent db via le contexte sans avoir besoin d’importer ou d’appeler getPrisma() elles-mêmes :
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' } }); });Déployer votre base de données
Section intitulée « Déployer votre base de données »Le générateur de base de données relationnelle crée une infrastructure CDK ou Terraform en fonction de votre iacProvider sélectionné.
La construction CDK est créée dans common/constructs. Exemple d’utilisation :
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, } }); }}Cela provisionne un cluster Aurora avec RDS Proxy, identifiants administrateur, utilisateur de base de données d’application, enregistrement de configuration d’exécution et gestionnaire de migration.
L’infrastructure générée crée deux utilisateurs de base de données :
- Utilisateur administrateur - Créé lors du provisionnement du cluster avec les identifiants stockés dans AWS Secrets Manager
- Utilisateur d’application - Créé via une ressource personnalisée Lambda avec l’authentification IAM activée et tous les privilèges sur la base de données d’application
Le module Terraform est créé dans common/terraform. Exemple d’utilisation :
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}Cela provisionne un cluster Aurora avec RDS Proxy, identifiants administrateur, Lambda create-db-user, enregistrement de configuration d’exécution, Lambda de migration et ressources de registre de conteneurs.
L’infrastructure générée crée deux utilisateurs de base de données :
- Utilisateur administrateur - Créé lors du provisionnement du cluster avec les identifiants stockés dans AWS Secrets Manager
- Utilisateur d’application - Créé via une fonction Lambda avec l’authentification IAM activée et tous les privilèges sur la base de données d’application
L’utilisateur d’application est automatiquement créé avec un nom aléatoire et l’authentification IAM. getPrisma() est déjà configuré pour s’authentifier en tant que cet utilisateur en utilisant des jetons RDS de courte durée, de sorte que votre code d’application ne gère jamais les mots de passe de base de données.
Votre VPC doit inclure des sous-réseaux publics, des sous-réseaux privés avec sortie et des sous-réseaux privés isolés. La base de données peut s’exécuter dans des sous-réseaux privés isolés, tandis que les fonctions Lambda de l’API doivent s’exécuter dans des sous-réseaux privés avec sortie afin qu’elles puissent atteindre les services AWS tels qu’AppConfig.
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}Connecter une API à la base de données
Section intitulée « Connecter une API à la base de données »Dans votre stack d’application, déployez l’API dans le même VPC que la base de données, puis appelez allowDefaultPortFrom et grantConnect pour ouvrir le chemin réseau et accorder la permission IAM rds-db:connect à chaque gestionnaire Lambda :
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);});Déployez les fonctions Lambda de l’API dans un sous-réseau privé avec sortie (recommandé) ou un sous-réseau public, pas un sous-réseau privé isolé. À l’exécution, getPrisma() récupère les détails de connexion à la base de données depuis AWS AppConfig, qui est un point de terminaison de service AWS public. Les fonctions Lambda dans un sous-réseau privé isolé n’ont pas d’accès Internet sortant et ne peuvent pas atteindre AppConfig. Les sous-réseaux privés avec sortie acheminent le trafic sortant via une passerelle NAT qui se trouve dans un sous-réseau public.
Transmettez les sorties du module de base de données dans votre module de calcul afin qu’il puisse atteindre la base de données et lire sa configuration d’exécution :
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
# Autoriser l'API à lire la configuration d'exécution depuis AppConfig appconfig_application_id = module.my_database.appconfig_application_id
# Accorder rds-db:connect pour l'utilisateur de base de données d'application database_cluster_resource_id = module.my_database.cluster_resource_id database_runtime_user = module.my_database.database_runtime_user
# Autoriser l'accès réseau au port de la base de données 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 }}Déployez les fonctions Lambda de l’API dans des sous-réseaux privés avec sortie (recommandé) ou des sous-réseaux publics, pas des sous-réseaux privés isolés. À l’exécution, getPrisma() récupère les détails de connexion à la base de données depuis AWS AppConfig, qui est un point de terminaison de service AWS public. Les fonctions Lambda dans un sous-réseau privé isolé n’ont pas d’accès Internet sortant et ne peuvent pas atteindre AppConfig. Les sous-réseaux privés avec sortie acheminent le trafic sortant via une passerelle NAT qui nécessite un sous-réseau public.
Assurez-vous que le rôle Lambda de l’API dispose de rds-db:connect sur arn:aws:rds-db:<region>:<account>:dbuser:<cluster_resource_id>/<database_runtime_user> et des permissions de lecture AppConfig, que le groupe de sécurité de l’API peut atteindre le groupe de sécurité de la base de données sur le port de la base de données, et que l’environnement Lambda inclut RUNTIME_CONFIG_APP_ID.
Configuration RDS Proxy
Section intitulée « Configuration RDS Proxy »L’infrastructure générée inclut un RDS Proxy par défaut, qui se situe entre votre application et le cluster Aurora. RDS Proxy offre plusieurs avantages :
- Pooling de connexions - Maintient un pool de connexions de base de données qui peuvent être partagées entre les instances d’application, réduisant la surcharge d’établissement de nouvelles connexions
- Résilience des connexions - Gère automatiquement les basculements et les reconnexions lors des remplacements d’instances Aurora ou de la maintenance
- Authentification IAM - Prend en charge l’authentification de base de données basée sur IAM, éliminant le besoin de gérer les identifiants de base de données dans votre code d’application
- Sécurité améliorée - Impose le chiffrement TLS pour toutes les connexions
Désactiver RDS Proxy
Section intitulée « Désactiver RDS Proxy »Vous pouvez désactiver le proxy RDS comme suit :
import { MyDatabase } from ':my-scope/common-constructs';
const db = new MyDatabase(this, 'Db', { ... enableRdsProxy: false,});Lorsque RDS Proxy est désactivé, votre application se connecte directement au point de terminaison du cluster Aurora.
Pour les connexions directes au cluster Aurora depuis les environnements d’exécution Lambda Node.js 20 ou ultérieur, configurez la fonction Lambda pour charger le bundle CA Amazon RDS :
const api = new Api(this, 'Api', { integrations: Api.defaultIntegrations(this) .withDefaultOptions({ environment: { NODE_EXTRA_CA_CERTS: '/var/runtime/ca-cert.pem', }, }) .build(),});Par défaut, RDS Proxy est activé. Le client d’exécution généré (getPrisma()) se connecte automatiquement via le point de terminaison du proxy. Vous pouvez le désactiver si nécessaire :
module "my_database" { source = "../../common/terraform/src/app/dbs/my-database" ... enable_rds_proxy = false}Lorsque RDS Proxy est désactivé, votre application se connecte directement au point de terminaison du cluster Aurora.
Pour les connexions directes au cluster Aurora depuis les environnements d’exécution Lambda Node.js 20 ou ultérieur, configurez la fonction Lambda pour charger le bundle CA Amazon RDS :
module "api" { source = "..." ...
environment_variables = { NODE_EXTRA_CA_CERTS = "/var/runtime/ca-cert.pem" }}Pour plus de détails, consultez les exigences SSL/TLS pour les connexions Amazon RDS d’AWS Lambda et la documentation TLS d’Amazon RDS Proxy. Lors de l’utilisation de RDS Proxy, vous n’avez pas besoin de configurer le bundle CA RDS dans votre fonction Lambda.
L’infrastructure générée peut être personnalisée pour correspondre aux exigences de votre charge de travail. Les exemples suivants démontrent quelques options de personnalisation courantes disponibles.
Instances du cluster
Section intitulée « Instances du cluster »Configurez les instances writer et reader pour votre cluster Aurora.
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}Capacité Serverless
Section intitulée « Capacité Serverless »Contrôlez les limites de mise à l’échelle d’Aurora Serverless v2 pour correspondre à votre charge de travail.
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}Version du moteur
Section intitulée « Version du moteur »Épinglez une version spécifique du moteur Aurora.
Par défaut, l’image Docker de base de données locale générée correspond à la version du moteur Aurora par défaut. Si vous modifiez la version du moteur Aurora, il est recommandé d’utiliser également une version de base de données Docker locale correspondante pour une compatibilité maximale. Consultez les notes de version AWS pour les versions Aurora PostgreSQL et les versions Aurora MySQL pour identifier la version de base de données communautaire correspondante.
L’image de base de données locale est configurée dans la cible serve-local du projet de base de données généré dans project.json. Mettez à jour l’argument d’image transmis à scripts/docker-start.ts lorsque vous modifiez les versions du moteur.
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"}Protection contre la suppression
Section intitulée « Protection contre la suppression »La protection contre la suppression est activée par défaut (deletionProtection: true dans CDK, deletion_protection = true dans Terraform) pour protéger le cluster Aurora contre la suppression accidentelle.
Désactiver la protection contre la suppression
Section intitulée « Désactiver la protection contre la suppression »Vous pouvez désactiver la protection contre la suppression pour les environnements où la suppression de la base de données est attendue, tels que les stacks de développement ou de prévisualisation éphémères.
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}Politique de suppression
Section intitulée « Politique de suppression »La construction CDK conserve le cluster Aurora par défaut (removalPolicy: RemovalPolicy.RETAIN). Modifiez cela lorsque vous souhaitez que la suppression de la stack CDK crée un instantané ou détruise le cluster à la place.
Lors de l’utilisation de RemovalPolicy.DESTROY, la protection contre la suppression doit également être désactivée avant que le cluster puisse être supprimé.
import { RemovalPolicy } from 'aws-cdk-lib';import { MyDatabase } from ':my-scope/common-constructs';
const db = new MyDatabase(this, 'Db', { ... removalPolicy: RemovalPolicy.SNAPSHOT,});Pour un environnement éphémère où la base de données doit être supprimée avec la stack :
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 n’utilise pas les politiques de suppression CDK. Par défaut, le module crée un instantané final lors de la suppression (skip_final_snapshot = false). Pour ignorer l’instantané final pour un environnement éphémère :
module "my_database" { source = "../../common/terraform/src/app/dbs/my-database" ... deletion_protection = false skip_final_snapshot = true}Rotation de clé de chiffrement
Section intitulée « Rotation de clé de chiffrement »La clé KMS utilisée pour chiffrer le cluster Aurora et son secret d’identifiants a la rotation automatique de clé activée par défaut. Désactivez-la si votre politique de sécurité gère la rotation en externe.
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}Limitations
Section intitulée « Limitations »MySQL : Mode de streaming API Gateway
Section intitulée « MySQL : Mode de streaming API Gateway »Lors de l’utilisation d’Aurora MySQL avec des réponses en streaming API Gateway (par exemple avec le httpBatchStreamLink de tRPC), le client MySQL Prisma conserve la boucle d’événements Node.js après la fin d’une requête, empêchant le Lambda de vider le flux et de terminer la requête.
Pour contourner ce problème, déconnectez explicitement le client dans un bloc finally après chaque requête afin que la boucle d’événements soit libre de se terminer et que la réponse en streaming puisse se terminer.
Option 1 : par procédure
export const listExampleTable = publicProcedure .output(z.array(ExampleTableSchema)) .query(async () => { const prisma = await getPrisma(); try { return await prisma.exampleTable.findMany(); } finally { await prisma.$disconnect(); } });Option 2 : middleware tRPC
Si vous utilisez le modèle de middleware, ajoutez l’appel $disconnect() au middleware afin que toutes les procédures construites dessus soient couvertes automatiquement :
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 : Expiration du jeton IAM
Section intitulée « MySQL : Expiration du jeton IAM »Les jetons d’authentification IAM RDS expirent après 15 minutes. Le client MySQL Prisma capture le jeton IAM comme une valeur statique au moment où getPrisma() est appelé. Une connexion ouverte existante n’est pas affectée, mais si une nouvelle connexion doit être établie après l’expiration du jeton, l’authentification échouera. L’adaptateur PostgreSQL évite cela en rafraîchissant le jeton dynamiquement chaque fois que le pool ouvre une nouvelle connexion, mais l’adaptateur MySQL n’a pas de mécanisme équivalent.
Pour les tâches de longue durée telles que les travaux par lots ou les migrations de données, appelez getPrisma() au début de chaque unité de travail plutôt qu’une fois pour l’ensemble de l’opération. Parce que getPrisma() crée toujours un nouveau client et récupère un nouveau jeton IAM pour MySQL, cela garantit que chaque connexion s’authentifie avec un jeton valide.