Banco de Dados Relacional TypeScript
Este gerador cria um novo projeto de banco de dados relacional apoiado por 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:
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- 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
| 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. |
| infra | aurora | none | aurora | Serviço de banco de dados relacional a ser provisionado. |
| engine | postgres | mysql | postgres | 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. |
| framework | prisma | prisma | Framework ORM a ser usado para o projeto gerado. |
| iac | inherit | cdk | terraform | inherit | O provedor IaC preferido. Por padrão, isso é herdado da sua seleção inicial. |
| preferInstallDependencies | boolean | true | Se deve preferir instalar dependências após a execução do gerador. Defina como false para adiar a instalação ao executar múltiplos geradores em lote (uma instalação ainda é executada se necessário para que geradores subsequentes possam calcular o grafo de projetos Nx); instale uma vez no final. |
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 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
Scripts de desenvolvimento local são compartilhados entre todos os projetos de banco de dados e gerados em 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)
Infraestrutura
Seção intitulada “Infraestrutura”Como este gerador fornece infraestrutura como código baseada no seu iac escolhido, ele criará um projeto em packages/common que inclui os constructs CDK relevantes ou módulos Terraform.
O projeto comum de infraestrutura como código é estruturado da seguinte forma:
Directorypackages/common/constructs
Directorysrc
Directoryapp/ Constructs for infrastructure specific to a project/generator
- …
Directorycore/ Generic constructs which are reused by constructs in
app- …
- index.ts Entry point exporting constructs from
app
- project.json Project build targets and configuration
Directorypackages/common/terraform
Directorysrc
Directoryapp/ Terraform modules for infrastructure specific to a project/generator
- …
Directorycore/ Generic modules which are reused by modules in
app- …
- project.json Project build targets and configuration
Directorypackages/common/constructs/src
Directoryapp
Directorydbs
- <name>.ts Infraestrutura específica para seu banco de dados
Directorycore
Directoryrdb
- aurora.ts Construto 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
Arquitetura
Seção intitulada “Arquitetura”O banco de dados implantado possui a seguinte arquitetura. Por padrão, um Amazon RDS Proxy fica na frente do cluster Aurora para agrupar conexões e habilitar autenticação IAM — veja Desabilitar RDS Proxy para a alternativa. A arquitetura é a mesma independentemente de você selecionar o mecanismo PostgreSQL ou MySQL; apenas o tipo de mecanismo Aurora difere.
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 do Banco de Dados
Seção intitulada “Gerando o Cliente do Banco de Dados”O gerador configura automaticamente o target 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 run <your-db-project-name>:generateyarn nx run <your-db-project-name>:generatenpx nx run <your-db-project-name>:generatebunx nx run <your-db-project-name>:generateUse o target 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:
getPrisma()- 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
- Lida com 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”Depois de 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 target prisma gerado inicia automaticamente um contêiner de banco de dados local 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 stack 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ê obtém 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 do Prisma
Seção intitulada “Executando Comandos do Prisma”O target prisma gerado expõe a CLI do Prisma, para que você possa usá-la para executar qualquer comando suportado pelo Prisma no 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>Usando o Prisma Studio
Seção intitulada “Usando o Prisma Studio”Prisma Studio é um editor visual para seu banco de dados local. Use-o para navegar por 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 popular 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 studioParando o Banco de Dados Local
Seção intitulada “Parando o Banco de Dados Local”Parar dev (por exemplo, com Ctrl+C) remove automaticamente o contêiner do banco de dados local, mas preserva o volume nomeado para que seus dados persistam entre reinicializações.
Conectando ao Banco de Dados
Seção intitulada “Conectando ao Banco de Dados”Em qualquer projeto TypeScript, importe getPrisma do seu pacote de banco de dados e chame-o para obter um cliente Prisma com segurança de tipos:
import { getPrisma } from '@my-scope/db';
const prisma = await getPrisma();const users = await 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 do 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 do banco de dados até a resposta da sua API.
getPrisma() busca as configurações de conexão do banco de dados do AWS AppConfig em tempo de execução.
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 iac selecionado.
O construto 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 DML (SELECT, INSERT, UPDATE, DELETE) 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"
# Database subnets have no internet route; Lambda subnets need NAT egress. vpc_id = aws_vpc.main.id database_subnet_ids = aws_subnet.database[*].id lambda_subnet_ids = aws_subnet.private[*].id
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 contêiner.
O módulo de banco de dados registra seus detalhes de conexão sob o namespace de configuração de runtime database. Inclua este namespace ao instanciar a aplicação AppConfig de configuração de runtime compartilhada:
module "runtime_config_appconfig" { source = "../../common/terraform/src/core/runtime-config/appconfig"
application_name = "my-app-runtime-config" namespaces = ["connection", "agentcore", "database"]}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 DML (SELECT, INSERT, UPDATE, DELETE) no banco de dados da aplicação
O usuário da aplicação é criado automaticamente com um nome aleatório e autenticação IAM. O cliente de banco de dados gerado 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 saída e sub-redes privadas isoladas. O banco de dados pode ser executado em sub-redes privadas isoladas, enquanto as funções Lambda da aplicação devem ser executadas em sub-redes privadas com saída para que possam alcançar serviços AWS como AppConfig.
Exemplo de configuração de VPC
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, }, ],});data "aws_availability_zones" "available" { state = "available"}
resource "aws_vpc" "main" { cidr_block = "10.0.0.0/16" enable_dns_hostnames = true enable_dns_support = true}
# Isolated subnets for the database: no route to the internetresource "aws_subnet" "database" { count = 2 vpc_id = aws_vpc.main.id cidr_block = cidrsubnet(aws_vpc.main.cidr_block, 8, count.index) availability_zone = data.aws_availability_zones.available.names[count.index]}
# Private subnets with NAT egress for Lambda functions and runtimes,# so they can reach AWS services such as AppConfigresource "aws_subnet" "private" { count = 2 vpc_id = aws_vpc.main.id cidr_block = cidrsubnet(aws_vpc.main.cidr_block, 8, count.index + 2) availability_zone = data.aws_availability_zones.available.names[count.index]}
# Public subnet hosting the NAT gatewayresource "aws_subnet" "public" { vpc_id = aws_vpc.main.id cidr_block = cidrsubnet(aws_vpc.main.cidr_block, 8, 4) availability_zone = data.aws_availability_zones.available.names[0]}
resource "aws_internet_gateway" "main" { vpc_id = aws_vpc.main.id}
resource "aws_route_table" "public" { vpc_id = aws_vpc.main.id
route { cidr_block = "0.0.0.0/0" gateway_id = aws_internet_gateway.main.id }}
resource "aws_route_table_association" "public" { subnet_id = aws_subnet.public.id route_table_id = aws_route_table.public.id}
resource "aws_eip" "nat" { domain = "vpc"}
resource "aws_nat_gateway" "main" { allocation_id = aws_eip.nat.id subnet_id = aws_subnet.public.id depends_on = [aws_internet_gateway.main]}
resource "aws_route_table" "private" { vpc_id = aws_vpc.main.id
route { cidr_block = "0.0.0.0/0" nat_gateway_id = aws_nat_gateway.main.id }}
resource "aws_route_table_association" "private" { count = 2 subnet_id = aws_subnet.private[count.index].id route_table_id = aws_route_table.private.id}Use o gerador connection para conectar um projeto a este banco de dados — consulte o guia de conexão para o tipo de computação relevante (por exemplo, FastAPI, servidor MCP, agente) para a configuração de infraestrutura necessária para alcançá-lo.
Verificação de Imagem
Seção intitulada “Verificação de Imagem”A imagem Docker construída para este projeto pode ser verificada em busca de vulnerabilidades usando Trivy, executando a partir da imagem Trivy hospedada no ECR.
Um target trivy é adicionado ao seu projeto que verifica a imagem construída e sai com código diferente de zero se alguma vulnerabilidade de severidade HIGH ou CRITICAL for encontrada. O Dockerfile gerado usa uma imagem base sem vulnerabilidades corrigíveis conhecidas dessas severidades no momento da geração, e atualiza as ferramentas incluídas (como npm) para mantê-lo assim.
A verificação usa o mesmo mecanismo de contêiner que sua construção de imagem (docker ou finch), portanto nenhuma ferramenta adicional é necessária. Como a verificação só é executada novamente quando a imagem muda, uma imagem inalterada não é verificada novamente. O script raiz trivy fornecido verifica todas as imagens no workspace:
pnpm trivyyarn trivynpm run trivybun trivySuprimindo Descobertas do Trivy
Seção intitulada “Suprimindo Descobertas do Trivy”Pode haver casos em que você deseja suprimir uma vulnerabilidade específica, por exemplo, quando nenhuma correção está disponível ainda e você avaliou o risco como aceitável.
Adicione o ID da vulnerabilidade (um por linha) ao arquivo .trivyignore na raiz do seu projeto (ou seja, ao lado do seu project.json):
# node-tar arbitrary file write - not exploitable in our usageCVE-2024-XXXXXPara mais detalhes sobre filtragem de descobertas, consulte a documentação de filtragem do Trivy.
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 - Lida automaticamente com 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 o RDS Proxy
Seção intitulada “Desabilitar o 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.
Por padrão, o RDS Proxy está habilitado. 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.
Requisitos SSL ao Conectar sem RDS Proxy
Seção intitulada “Requisitos SSL ao Conectar sem RDS Proxy”Ao conectar diretamente ao cluster Aurora (sem RDS Proxy), o runtime que chama getPrisma() deve confiar no pacote de CA do Amazon RDS. O cliente Prisma gerado habilita a verificação de certificado; como você disponibiliza o pacote de CA depende do runtime que se conecta ao banco de dados.
Para Amazon RDS, use o pacote de CA global de:
https://truststore.pki.rds.amazonaws.com/global/global-bundle.pemImagens de Contêiner de Runtime
Seção intitulada “Imagens de Contêiner de Runtime”Se você preparar sua própria imagem de contêiner para o runtime, baixe o pacote de CA do RDS no seu Dockerfile e adicione-o ao armazenamento de confiança do sistema operacional.
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-trustRUN apt-get update && apt-get install -y --no-install-recommends curl ca-certificates && \ rm -rf /var/lib/apt/lists/* && \ curl -fsSL "https://truststore.pki.rds.amazonaws.com/global/global-bundle.pem" \ -o /usr/local/share/ca-certificates/rds-bundle.crt && \ update-ca-certificatesFunções Lambda Zipadas
Seção intitulada “Funções Lambda Zipadas”Para funções Lambda zipadas usando runtimes Node.js 20 ou posterior, carregue o pacote de CA do Amazon RDS definindo NODE_EXTRA_CA_CERTS:
const api = new Api(this, 'Api', { integrations: Api.defaultIntegrations(this) .withDefaultOptions({ environment: { NODE_EXTRA_CA_CERTS: '/var/runtime/ca-cert.pem', }, }) .build(),});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. Ao usar RDS Proxy, você não precisa configurar o pacote de CA do RDS no runtime que se conecta ao banco de dados.
Instâncias do Cluster
Seção intitulada “Instâncias do Cluster”Configure as instâncias de escritor e leitor para o 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 escalabilidade 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 Motor
Seção intitulada “Versão do Motor”Fixe uma versão específica do motor Aurora.
Por padrão, a imagem do contêiner do banco de dados local gerada corresponde à versão padrão do motor Aurora. Se você alterar a versão do motor Aurora, é recomendável também usar uma versão de imagem de contêiner local correspondente para máxima compatibilidade. Consulte as notas de versão 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 campo localDev.image do arquivo config.json gerado na raiz do seu projeto de banco de dados. Atualize esse valor quando você alterar as versões do motor.
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 stacks 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 construto CDK retém o cluster Aurora por padrão (removalPolicy: RemovalPolicy.RETAIN). Altere isso quando você quiser que a exclusão da stack CDK faça um 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 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ã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}Registro e Monitoramento
Seção intitulada “Registro e Monitoramento”O log postgresql é exportado para Aurora PostgreSQL, com registro limitado apenas a instruções DDL (log_statement=ddl), de modo que os valores dos parâmetros das instruções nunca são registrados — desde que cada instrução seja enviada individualmente. log_statement=ddl registra todo o texto bruto de um lote de múltiplas instruções (por exemplo, uma única chamada psql -c "a;b;c") literalmente se qualquer instrução nele for DDL, incluindo quaisquer valores DML nesse mesmo lote.
Os logs audit e error são exportados para Aurora MySQL — general e slowquery são deliberadamente excluídos, pois registram o texto completo das instruções, incluindo valores DML. Advanced Auditing tem escopo limitado a conexões e DDL (server_audit_events=CONNECT,QUERY_DDL), portanto, os valores dos parâmetros das instruções nunca são registrados.
O Performance Insights está habilitado na instância de gravação do Aurora por padrão (criptografado com a chave KMS do cluster). Os logs do mecanismo Aurora também são exportados para o CloudWatch Logs por padrão, configurados para exibir atividade no nível de esquema sem vazar dados de linha.
Desabilite a exportação de logs por banco de dados se não for necessário:
import { MyDatabase } from '@my-scope/common-constructs';
const db = new MyDatabase(this, 'Db', { ... enableCloudwatchLogs: false, enablePerformanceInsights: false,});module "my_database" { source = "../../common/terraform/src/app/dbs/my-database" ... enable_cloudwatch_logs = false # disable if not required enable_performance_insights = false # disable if not required}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 segredo de credenciais tem a 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 loop de eventos do Node.js após a conclusão de uma consulta, impedindo que o Lambda libere o stream e encerre a solicitação.
Para contornar isso, desconecte explicitamente o cliente em um bloco finally após cada consulta para que o loop de eventos 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 do Token IAM
Seção intitulada “MySQL: Expiração do Token IAM”Tokens de autenticação IAM do RDS expiram após 15 minutos. O cliente Prisma MySQL 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 possui mecanismo equivalente.
Para tarefas de longa duração, como trabalhos 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.
Conexões
Seção intitulada “Conexões”Use o gerador connection para integrar este projeto com outros no seu workspace. As seguintes conexões envolvem este projeto: