Banco de Dados Relacional
Este gerador cria um novo projeto de banco de dados relacional baseado no Amazon Aurora (PostgreSQL ou MySQL) e Prisma ORM. Ele gera o código da aplicação e a infraestrutura necessária para provisionar e gerenciar um banco de dados usando AWS CDK ou Terraform, com definição de esquema declarativa, implantação automática de migrações e um cliente ORM com segurança de tipos.
Gerar um Banco de Dados Relacional
Seção intitulada “Gerar um Banco de Dados Relacional”Você pode gerar um novo projeto de banco de dados relacional de duas maneiras:
- Instale o Nx Console VSCode Plugin se ainda não o fez
- Abra o console Nx no VSCode
- Clique em
Generate (UI)na seção "Common Nx Commands" - Procure por
@aws/nx-plugin - ts#rdb - Preencha os parâmetros obrigatórios
- Clique em
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#rdbVocê também pode realizar uma execução simulada para ver quais arquivos seriam alterados
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| Parâmetro | Tipo | Padrão | Descrição |
|---|---|---|---|
| name Obrigatório | string | - | Nome do projeto de banco de dados a ser gerado |
| directory | string | packages | O diretório onde armazenar a aplicação. |
| subDirectory | string | - | O subdiretório onde o projeto é colocado. Por padrão, este é o nome do projeto. |
| service Obrigatório | string | Aurora | Serviço de banco de dados relacional a ser provisionado. |
| engine Obrigatório | string | PostgreSQL | Motor de banco de dados a ser usado com o serviço selecionado. |
| databaseUser | string | dbadmin | Nome de usuário do administrador do banco de dados. O padrão é 'dbadmin'. |
| databaseName | string | - | Nome inicial do banco de dados. O padrão é o nome do projeto. |
| ormFramework Obrigatório | string | Prisma | Framework ORM a ser usado para o projeto gerado. |
| iacProvider | string | Inherit | O provedor IaC preferido. Por padrão, este é herdado da sua seleção inicial. |
Saída do Gerador
Seção intitulada “Saída do Gerador”O gerador criará a seguinte estrutura de projeto no diretório <directory>/<name>:
Directoryprisma
Directorymodels
- example.prisma Definição de modelo de exemplo
- schema.prisma Esquema principal do Prisma (referencia modelos)
Directoryscripts
- docker-pull.ts Baixa a imagem Docker do banco de dados para desenvolvimento local
- docker-start.ts Inicia um container de banco de dados local
- wait-for-db.ts Aguarda o banco de dados local estar pronto
Directorysrc
- index.ts Ponto de entrada do projeto
- constants.ts Detalhes de conexão de desenvolvimento local e chave de configuração de runtime
- prisma.ts Wrapper do cliente Prisma de runtime
- utils.ts Auxiliares de configuração de runtime e secrets
- create-db-user-handler.ts Manipulador Lambda usado para criar o usuário de banco de dados da aplicação durante a implantação
- migration-handler.ts Manipulador Lambda usado para executar migrações de banco de dados durante a implantação
- .gitignore Entradas do Git ignore incluindo a saída do cliente Prisma gerado
- Dockerfile Definição de imagem de container para o manipulador de migração
- project.json Configuração do projeto e alvos de build
- prisma.config.ts Configuração para Prisma CLI
Infraestrutura
Seção intitulada “Infraestrutura”Como este gerador fornece infraestrutura como código com base no iacProvider escolhido, ele criará um projeto em packages/common que inclui os constructs CDK ou módulos Terraform relevantes.
O projeto comum de infraestrutura como código está estruturado da seguinte forma:
Directorypackages/common/constructs
Directorysrc
Directoryapp/ Constructs para infraestrutura específica de um projeto/gerador
- …
Directorycore/ Constructs genéricos reutilizados pelos constructs em
app- …
- index.ts Ponto de entrada exportando os constructs de
app
- project.json Metas de build e configuração do projeto
Directorypackages/common/terraform
Directorysrc
Directoryapp/ Módulos Terraform para infraestrutura específica de um projeto/gerador
- …
Directorycore/ Módulos genéricos reutilizados pelos módulos em
app- …
- project.json Metas de build e configuração do projeto
Directorypackages/common/constructs/src
Directoryapp
Directorydbs
- <name>.ts Infraestrutura específica para seu banco de dados
Directorycore
Directoryrdb
- aurora.ts Construtor genérico de banco de dados Aurora
Directorypackages/common/terraform/src
Directoryapp
Directorydbs
Directory<name>
- <name>.tf Módulo específico para seu banco de dados
Directorycore
Directoryrdb
Directoryaurora
- aurora.tf Módulo genérico Aurora
Desenvolvimento Local
Seção intitulada “Desenvolvimento Local”Modelagem de Dados
Seção intitulada “Modelagem de Dados”O projeto gerado usa Prisma ORM para definir seu esquema de banco de dados e gerar um cliente com segurança de tipos. O fluxo de trabalho é model-first: adicione ou atualize arquivos de modelo Prisma no diretório prisma/models/ do seu projeto de banco de dados, depois gere uma migração a partir dessas alterações de modelo.
Exemplo de modelo User:
model User { id Int @id @default(autoincrement()) firstName String lastName String}Para mais detalhes, consulte o guia oficial de modelagem de dados do Prisma.
Gerando o Cliente de Banco de Dados
Seção intitulada “Gerando o Cliente de Banco de Dados”O gerador configura automaticamente o alvo generate para criar um cliente Prisma TypeScript com segurança de tipos sempre que você compilar o projeto. O cliente é escrito em generated/prisma (adicionado ao .gitignore).
Você também pode gerar manualmente o cliente a qualquer momento:
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>Use o alvo prisma para executar comandos da CLI do Prisma a partir da raiz do workspace:
pnpm nx run <project>:prisma generateyarn nx run <project>:prisma generatenpx nx run <project>:prisma generatebunx nx run <project>:prisma generateO wrapper de runtime em src/prisma.ts exporta:
DB_PACKAGE_NAME- a chave usada sob o namespace de configuração de runtimedatabaseno AWS AppConfiggetPrisma()- carrega as configurações de conexão do banco de dados do AWS AppConfig e cria um cliente Prisma usando autenticação IAM
O cliente automaticamente:
- Recupera a configuração do banco de dados do AWS AppConfig usando a variável de ambiente
RUNTIME_CONFIG_APP_ID - Gera tokens de autenticação temporários via AWS RDS Signer para autenticação IAM
- Gerencia conexões SSL/TLS com validação de certificado
- Manipula pooling de conexões através de pools de conexão de banco de dados persistentes
Criando Migrações
Seção intitulada “Criando Migrações”Após adicionar ou atualizar modelos em prisma/models/, use migrate dev para gerar arquivos de migração e aplicá-los ao seu banco de dados local ao mesmo tempo.
O alvo prisma gerado inicia automaticamente um banco de dados local via Docker antes de executar:
pnpm nx run <project>:prisma migrate devyarn nx run <project>:prisma migrate devnpx nx run <project>:prisma migrate devbunx nx run <project>:prisma migrate devSe você quiser apenas gerar os arquivos de migração sem aplicá-los ao banco de dados local, adicione --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-onlyIsso gera uma nova pasta de migração em prisma/migrations cada vez que seu esquema muda:
Directoryprisma
Directorymigrations
Directory20260405013911_initial_migrations
- migration.sql
- migration_lock.toml
- schema.prisma
Quando você implanta a pilha AWS, a infraestrutura gerada aplica automaticamente as migrações geradas ao banco de dados implantado.
Aplicando Migrações Existentes
Seção intitulada “Aplicando Migrações Existentes”Quando você baixa arquivos de migração criados por outros desenvolvedores, use migrate deploy para aplicar essas migrações existentes ao seu banco de dados local.
pnpm nx run <project>:prisma migrate deployyarn nx run <project>:prisma migrate deploynpx nx run <project>:prisma migrate deploybunx nx run <project>:prisma migrate deployNeste fluxo de desenvolvimento local, migrate deploy aplica os arquivos de migração ao seu banco de dados local; ele não implanta o banco de dados na AWS.
Executando Comandos Prisma
Seção intitulada “Executando Comandos Prisma”O alvo prisma gerado expõe a CLI do Prisma, então você pode usá-lo para executar qualquer comando suportado pelo Prisma contra o banco de dados local. Consulte a referência da CLI do Prisma para comandos disponíveis.
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
Seção intitulada “Prisma Studio”Prisma Studio é um editor visual para seu banco de dados local. Use-o para navegar em tabelas, inspecionar e editar registros, filtrar dados, seguir relações e executar SQL bruto através do console SQL integrado. É útil para verificar migrações e semear dados de teste durante o desenvolvimento. Inicie-o com:
pnpm nx run <project>:prisma studioyarn nx run <project>:prisma studionpx nx run <project>:prisma studiobunx nx run <project>:prisma studioConectando a partir de uma API tRPC
Seção intitulada “Conectando a partir de uma API tRPC”Embora esta seção descreva como conectar ao seu banco de dados a partir de uma API tRPC, ela também serve como referência para uso em qualquer outro projeto TypeScript.
Usando o Cliente Prisma em Manipuladores
Seção intitulada “Usando o Cliente Prisma em Manipuladores”Importe getPrisma do seu pacote de banco de dados e chame-o dentro do seu manipulador para obter um cliente Prisma com segurança de tipos:
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() retorna um cliente inicializado preguiçosamente e em cache. Chamadas subsequentes dentro do mesmo contexto de execução Lambda reutilizam o pool de conexões existente em vez de abrir um novo.
O cliente Prisma expõe modelos totalmente tipados derivados do seu esquema prisma/models/, fornecendo segurança de tipos de ponta a ponta desde o banco de dados até a resposta da sua API.
Injetando o Cliente Prisma via Middleware
Seção intitulada “Injetando o Cliente Prisma via Middleware”Em vez de chamar getPrisma() em cada procedimento, você também pode resolvê-lo uma vez em um middleware e anexá-lo ao contexto tRPC para que todos os procedimentos downstream possam acessá-lo diretamente.
Primeiro, defina o plugin em src/middleware/db.ts seguindo o mesmo padrão do middleware gerado:
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, }, }); });};Em seguida, concatene-o a um procedimento base na sua inicialização tRPC:
import { createDbPlugin } from './middleware/db.js';
export const dbProcedure = publicProcedure.concat(createDbPlugin());Procedimentos construídos em dbProcedure recebem db através do contexto sem precisar importar ou chamar getPrisma():
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' } }); });Implantando seu Banco de Dados
Seção intitulada “Implantando seu Banco de Dados”O gerador de banco de dados relacional cria infraestrutura CDK ou Terraform com base no seu iacProvider selecionado.
O construtor CDK é criado em common/constructs. Exemplo de uso:
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, } }); }}Isso provisiona um cluster Aurora com RDS Proxy, credenciais de administrador, usuário de banco de dados da aplicação, registro de configuração de runtime e manipulador de migração.
A infraestrutura gerada cria dois usuários de banco de dados:
- Usuário administrador - Criado durante o provisionamento do cluster com credenciais armazenadas no AWS Secrets Manager
- Usuário da aplicação - Criado via um recurso personalizado Lambda com autenticação IAM habilitada e privilégios completos no banco de dados da aplicação
O módulo Terraform é criado em common/terraform. Exemplo de uso:
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}Isso provisiona um cluster Aurora com RDS Proxy, credenciais de administrador, Lambda create-db-user, registro de configuração de runtime, Lambda de migração e recursos de registro de container.
A infraestrutura gerada cria dois usuários de banco de dados:
- Usuário administrador - Criado durante o provisionamento do cluster com credenciais armazenadas no AWS Secrets Manager
- Usuário da aplicação - Criado via uma função Lambda com autenticação IAM habilitada e privilégios completos no banco de dados da aplicação
O usuário da aplicação é criado automaticamente com um nome aleatório e autenticação IAM. getPrisma() já está configurado para autenticar como este usuário usando tokens RDS de curta duração, então o código da sua aplicação nunca manipula senhas de banco de dados.
Sua VPC deve incluir sub-redes públicas, sub-redes privadas com egress e sub-redes privadas isoladas. O banco de dados pode ser executado em sub-redes privadas isoladas, enquanto as funções Lambda da API devem ser executadas em sub-redes privadas com egress para que possam alcançar serviços AWS como 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}Conectando uma API ao Banco de Dados
Seção intitulada “Conectando uma API ao Banco de Dados”Na sua pilha de aplicação, implante a API na mesma VPC que o banco de dados, depois chame allowDefaultPortFrom e grantConnect para abrir o caminho de rede e conceder permissão IAM rds-db:connect a cada manipulador 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);});Implante as funções Lambda da API em uma sub-rede privada com egress (recomendado) ou uma sub-rede pública, não uma sub-rede privada isolada. Em tempo de execução, getPrisma() recupera os detalhes de conexão do banco de dados do AWS AppConfig, que é um endpoint de serviço AWS público. Funções Lambda em uma sub-rede privada isolada não têm acesso de saída à internet e não podem alcançar o AppConfig. Sub-redes privadas com egress roteiam o tráfego de saída através de um NAT Gateway que fica em uma sub-rede pública.
Passe as saídas do módulo de banco de dados para o seu módulo de computação para que ele possa alcançar o banco de dados e ler sua configuração de runtime:
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
# Permitir que a API leia configuração de runtime do AppConfig appconfig_application_id = module.my_database.appconfig_application_id
# Conceder rds-db:connect para o usuário de banco de dados da aplicação database_cluster_resource_id = module.my_database.cluster_resource_id database_runtime_user = module.my_database.database_runtime_user
# Permitir acesso de rede à porta do banco de dados 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 }}Implante as funções Lambda da API em sub-redes privadas com egress (recomendado) ou sub-redes públicas, não sub-redes privadas isoladas. Em tempo de execução, getPrisma() recupera os detalhes de conexão do banco de dados do AWS AppConfig, que é um endpoint de serviço AWS público. Funções Lambda em uma sub-rede privada isolada não têm acesso de saída à internet e não podem alcançar o AppConfig. Sub-redes privadas com egress roteiam o tráfego de saída através de um NAT Gateway que requer uma sub-rede pública.
Certifique-se de que a role Lambda da API tenha rds-db:connect em arn:aws:rds-db:<region>:<account>:dbuser:<cluster_resource_id>/<database_runtime_user> e permissões de leitura do AppConfig, que o grupo de segurança da API possa alcançar o grupo de segurança do banco de dados na porta do banco de dados, e que o ambiente Lambda inclua RUNTIME_CONFIG_APP_ID.
Configuração do RDS Proxy
Seção intitulada “Configuração do RDS Proxy”A infraestrutura gerada inclui um RDS Proxy por padrão, que fica entre sua aplicação e o cluster Aurora. O RDS Proxy oferece vários benefícios:
- Pooling de conexões - Mantém um pool de conexões de banco de dados que podem ser compartilhadas entre instâncias da aplicação, reduzindo a sobrecarga de estabelecer novas conexões
- Resiliência de conexão - Manipula automaticamente failovers e reconexões durante substituições de instâncias Aurora ou manutenção
- Autenticação IAM - Suporta autenticação de banco de dados baseada em IAM, eliminando a necessidade de gerenciar credenciais de banco de dados no código da sua aplicação
- Segurança aprimorada - Impõe criptografia TLS para todas as conexões
Desabilitar RDS Proxy
Seção intitulada “Desabilitar RDS Proxy”Você pode desabilitar o proxy RDS da seguinte forma:
import { MyDatabase } from ':my-scope/common-constructs';
const db = new MyDatabase(this, 'Db', { ... enableRdsProxy: false,});Quando o RDS Proxy está desabilitado, sua aplicação se conecta diretamente ao endpoint do cluster Aurora.
Para conexões diretas ao cluster Aurora a partir de runtimes Lambda Node.js 20 ou posterior, configure a função Lambda para carregar o pacote de CA do Amazon RDS:
const api = new Api(this, 'Api', { integrations: Api.defaultIntegrations(this) .withDefaultOptions({ environment: { NODE_EXTRA_CA_CERTS: '/var/runtime/ca-cert.pem', }, }) .build(),});Por padrão, o RDS Proxy está habilitado. O cliente de runtime gerado (getPrisma()) conecta automaticamente através do endpoint do proxy. Você pode desabilitá-lo se necessário:
module "my_database" { source = "../../common/terraform/src/app/dbs/my-database" ... enable_rds_proxy = false}Quando o RDS Proxy está desabilitado, sua aplicação se conecta diretamente ao endpoint do cluster Aurora.
Para conexões diretas ao cluster Aurora a partir de runtimes Lambda Node.js 20 ou posterior, configure a função Lambda para carregar o pacote de CA do Amazon RDS:
module "api" { source = "..." ...
environment_variables = { NODE_EXTRA_CA_CERTS = "/var/runtime/ca-cert.pem" }}Para mais detalhes, consulte os requisitos SSL/TLS do AWS Lambda para conexões Amazon RDS e a documentação TLS do Amazon RDS Proxy. Ao usar RDS Proxy, você não precisa configurar o pacote de CA do RDS na sua função Lambda.
A infraestrutura gerada pode ser personalizada para corresponder aos requisitos da sua carga de trabalho. Os exemplos a seguir demonstram algumas opções de personalização comuns disponíveis.
Instâncias do Cluster
Seção intitulada “Instâncias do Cluster”Configure as instâncias writer e reader para seu 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}Capacidade Serverless
Seção intitulada “Capacidade Serverless”Controle os limites de escalonamento do Aurora Serverless v2 para corresponder à sua carga de trabalho.
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}Versão do Engine
Seção intitulada “Versão do Engine”Fixe uma versão específica do engine Aurora.
Por padrão, a imagem Docker do banco de dados local gerada corresponde à versão padrão do engine Aurora. Se você alterar a versão do engine Aurora, é recomendado também usar uma versão de banco de dados Docker local correspondente para máxima compatibilidade. Consulte as notas de lançamento da AWS para versões do Aurora PostgreSQL e versões do Aurora MySQL para identificar a versão correspondente do banco de dados da comunidade.
A imagem do banco de dados local é configurada no alvo serve-local do projeto de banco de dados gerado em project.json. Atualize o argumento de imagem passado para scripts/docker-start.ts quando você alterar as versões do engine.
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"}Proteção contra Exclusão
Seção intitulada “Proteção contra Exclusão”A proteção contra exclusão está habilitada por padrão (deletionProtection: true no CDK, deletion_protection = true no Terraform) para proteger o cluster Aurora contra exclusão acidental.
Desabilitar Proteção contra Exclusão
Seção intitulada “Desabilitar Proteção contra Exclusão”Você pode desabilitar a proteção contra exclusão para ambientes onde a exclusão do banco de dados é esperada, como pilhas de desenvolvimento ou preview de curta duração.
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}Política de Remoção
Seção intitulada “Política de Remoção”O construtor CDK retém o cluster Aurora por padrão (removalPolicy: RemovalPolicy.RETAIN). Altere isso quando você quiser que a exclusão da pilha CDK faça snapshot ou destrua o cluster.
Ao usar RemovalPolicy.DESTROY, a proteção contra exclusão também deve ser desabilitada antes que o cluster possa ser excluído.
import { RemovalPolicy } from 'aws-cdk-lib';import { MyDatabase } from ':my-scope/common-constructs';
const db = new MyDatabase(this, 'Db', { ... removalPolicy: RemovalPolicy.SNAPSHOT,});Para um ambiente efêmero onde o banco de dados deve ser excluído com a pilha:
import { RemovalPolicy } from 'aws-cdk-lib';import { MyDatabase } from ':my-scope/common-constructs';
const db = new MyDatabase(this, 'Db', { ... deletionProtection: false, removalPolicy: RemovalPolicy.DESTROY,});O Terraform não usa políticas de remoção do CDK. Por padrão, o módulo cria um snapshot final na exclusão (skip_final_snapshot = false). Para pular o snapshot final em um ambiente efêmero:
module "my_database" { source = "../../common/terraform/src/app/dbs/my-database" ... deletion_protection = false skip_final_snapshot = true}Rotação de Chave de Criptografia
Seção intitulada “Rotação de Chave de Criptografia”A chave KMS usada para criptografar o cluster Aurora e seu secret de credenciais tem rotação automática de chave habilitada por padrão. Desabilite-a se sua política de segurança gerenciar a rotação externamente.
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}Limitações
Seção intitulada “Limitações”MySQL: Modo de Streaming do API Gateway
Seção intitulada “MySQL: Modo de Streaming do API Gateway”Ao usar Aurora MySQL com respostas de streaming do API Gateway (por exemplo, com httpBatchStreamLink do tRPC), o cliente MySQL do Prisma mantém o event loop do Node.js após a conclusão de uma consulta, impedindo que o Lambda libere o stream e encerre a requisição.
Para contornar isso, desconecte explicitamente o cliente em um bloco finally após cada consulta para que o event loop fique livre para sair e a resposta de streaming possa ser concluída.
Opção 1: por procedimento
export const listExampleTable = publicProcedure .output(z.array(ExampleTableSchema)) .query(async () => { const prisma = await getPrisma(); try { return await prisma.exampleTable.findMany(); } finally { await prisma.$disconnect(); } });Opção 2: middleware tRPC
Se você estiver usando o padrão de middleware, adicione a chamada $disconnect() ao middleware para que todos os procedimentos construídos sobre ele sejam cobertos automaticamente:
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: Expiração de Token IAM
Seção intitulada “MySQL: Expiração de Token IAM”Tokens de autenticação IAM do RDS expiram após 15 minutos. O cliente MySQL do Prisma captura o token IAM como um valor estático no momento em que getPrisma() é chamado. Uma conexão aberta existente não é afetada, mas se uma nova conexão precisar ser estabelecida após o token ter expirado, a autenticação falhará. O adaptador PostgreSQL evita isso atualizando o token dinamicamente cada vez que o pool abre uma nova conexão, mas o adaptador MySQL não tem mecanismo equivalente.
Para tarefas de longa duração, como jobs em lote ou migrações de dados, chame getPrisma() no início de cada unidade de trabalho em vez de uma vez para toda a operação. Como getPrisma() sempre cria um cliente novo e busca um novo token IAM para MySQL, isso garante que cada conexão autentique com um token válido.