npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@elsikora/nestjs-typeorm-aws-connector

v1.4.1

Published

NestJS application configuration with AWS Parameter Store and TypeORM

Readme

💡 Highlights

  • 🔐 Zero-credential codebase — resolves all database config from AWS SSM Parameter Store & Secrets Manager at runtime
  • ♻️ Built-in automatic credential rotation with health checks, staged driver promotion, and graceful old-pool drainage
  • 🏗️ Split-source architecture — infra teams own host/port/secrets, app teams own pool/timeout/sync settings independently
  • 📦 Dual ESM/CJS module output with full TypeScript declarations and broad NestJS compatibility (v8–v11)

📚 Table of Contents

📖 Description

NestJS-TypeORM-AWS-Connector is a production-grade NestJS module that eliminates the pain of managing database configuration in AWS-hosted applications. Instead of hardcoding credentials or juggling environment variables, this connector resolves your entire TypeORM DataSourceOptions from AWS Systems Manager Parameter Store and AWS Secrets Manager — with built-in credential rotation.

In modern cloud-native architectures, database credentials are rotated regularly for security compliance. Traditional approaches break connections during rotation, causing downtime. This connector avoids destructive mid-run DataSource teardown by validating a replacement connection first, promoting the new driver for future query runners, and retiring the previous pool only after existing query runners drain.

Real-World Use Cases

  • ECS Fargate Microservices: Deploy NestJS APIs on Fargate where credentials are managed by AWS Secrets Manager with automatic rotation policies — the connector picks up fresh credentials without redeployment.
  • Multi-Environment Deployments: Use the same codebase across dev, staging, and production — each environment resolves its own database configuration from namespaced SSM parameters.
  • Aurora PostgreSQL / RDS MySQL: Connect to managed AWS databases where infrastructure teams control host, port, and secret references via Parameter Store, while application teams only configure entities and behavior.
  • Compliance-First Organizations: Meet SOC2 and PCI-DSS requirements by never storing credentials in code, environment files, or container images.

The connector uses a split-source model: infrastructure-owned parameters (host, port, secret ID) live in canonical AWS namespaces, while application-owned settings (pool size, timeouts, sync behavior) live in your app's namespace. Raw value overrides let you bypass SSM entirely for local development.

🛠️ Tech Stack

| Category | Technologies | |----------|-------------| | Language | TypeScript | | Runtime | Node.js | | Framework | NestJS | | ORM | TypeORM | | Cloud Services | AWS SSM Parameter Store, AWS Secrets Manager | | Build Tool | Rollup | | Linting | ESLint, Prettier | | CI/CD | GitHub Actions, Semantic Release | | Package Manager | npm |

🚀 Features

  • AWS Parameter Store Integration — Resolves database host, port, name, type, and tuning parameters from structured SSM paths with hierarchical namespace support
  • AWS Secrets Manager Integration — Fetches username/password credentials from Secrets Manager with proper error handling for missing or malformed secrets
  • Automatic Credential Rotation — Configurable interval-based rotation that validates a replacement connection before promoting it for future query runners
  • Emergency Recovery — After 3 consecutive rotation failures, automatically retries recovery without destructively tearing down the live DataSource
  • Connection Health Validation — Validates both existing and new connections with SELECT 1 queries before and after rotation
  • Split-Source Configuration Model — Infrastructure-owned settings (host, port, secret-id) use canonical AWS namespaces; app-owned settings use your module namespace
  • Raw Value Overrides — Bypass SSM entirely for any field by providing direct values — perfect for local development with host: '127.0.0.1'
  • Hierarchical Lookup Resolution — Field-level SSM lookup → canonical defaults → ssmLookupDefaults → ParameterStoreConfigModule defaults
  • Dual Module Format — Ships both ESM and CJS builds with full TypeScript declarations and source maps
  • Comprehensive Error Model — Contextual error messages include the failing field name and full structured lookup context for fast debugging
  • Broad NestJS Compatibility — Supports NestJS v8 through v11 as peer dependencies
  • Sync & Async Registration — Use register() for static config or registerAsync() with factory functions for dynamic configuration

🏗 Architecture

System Architecture

flowchart TD
    appModule[AppModule] --> paramStore[ParameterStoreConfigModule]
    appModule --> connectorModule[TypeOrmAwsConnectorModule]
    connectorModule --> connectorService[TypeOrmAwsConnectorService]
    connectorModule --> rotatorService[RotatorService]
    connectorModule --> scheduleModule[ScheduleModule]
    connectorService --> paramStoreService[ParameterStoreConfigService]
    connectorService --> configService[NestJS ConfigService]
    connectorService --> ssmParameterStore[AWS SSM Parameter Store]
    connectorService --> secretsManager[AWS Secrets Manager]
    rotatorService --> connectorService
    rotatorService --> dataSource[TypeORM DataSource]
    connectorModule --> typeOrmModule[TypeOrmModule.forRootAsync]

Data Flow

sequenceDiagram
    participant App as NestJS App
    participant Connector as ConnectorService
    participant SSM as AWS Parameter Store
    participant SM as AWS Secrets Manager
    participant TypeORM as TypeORM DataSource
    participant Rotator as RotatorService

    App->>Connector: getTypeOrmOptions()
    Connector->>SSM: Resolve host, port, dbName, type
    SSM-->>Connector: Parameter values
    Connector->>SSM: Resolve secretId
    SSM-->>Connector: Secret ID
    Connector->>SM: GetSecretValue(secretId)
    SM-->>Connector: username + password
    Connector->>SSM: Resolve optional tuning params
    SSM-->>Connector: poolSize, timeouts, etc.
    Connector-->>App: DataSourceOptions
    App->>TypeORM: Initialize DataSource

    loop Every rotation interval
        Rotator->>TypeORM: Validate connection health
        Rotator->>Connector: getTypeOrmOptions()
        Connector->>SM: Fetch fresh credentials
        SM-->>Connector: New username + password
        Rotator->>TypeORM: Initialize replacement DataSource
        Rotator->>TypeORM: Verify with SELECT 1
        Rotator->>TypeORM: Promote replacement driver for future query runners
        Rotator->>TypeORM: Retire previous pool after active query runners drain
    end

📁 Project Structure

NestJS-TypeORM-AWS-Connector/
├── .github/
│   ├── workflows/
│   │   ├── mirror-to-codecommit.yml
│   │   ├── qodana-quality-scan.yml
│   │   ├── release.yml
│   │   └── snyk-security-scan.yml
│   └── dependabot.yml
├── src/
│   ├── modules/
│   │   └── typeorm-aws-connector/
│   ├── shared/
│   │   ├── constant/
│   │   ├── enum/
│   │   ├── interface/
│   │   ├── provider/
│   │   └── type/
│   └── index.ts
├── CHANGELOG.md
├── commitlint.config.js
├── eslint.config.js
├── LICENSE
├── lint-staged.config.js
├── nest-cli.json
├── package-lock.json
├── package.json
├── prettier.config.js
├── README.md
├── release.config.js
├── rollup.config.js
├── tsconfig.build.json
└── tsconfig.json

📋 Prerequisites

  • Node.js >= 18.0.0
  • npm >= 9.0.0
  • @nestjs/common ^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0
  • @aws-sdk/client-ssm ^3.535.0
  • typeorm ^0.3.20
  • @elsikora/nestjs-aws-parameter-store-config ^2.0.1 (installed automatically)
  • AWS credentials configured (IAM role, environment variables, or AWS CLI profile)

🛠 Installation

# Install the connector and its required peer dependencies
npm install @elsikora/nestjs-typeorm-aws-connector @aws-sdk/client-ssm @nestjs/common typeorm

# The following are installed automatically as dependencies:
# @aws-sdk/client-secrets-manager
# @elsikora/nestjs-aws-parameter-store-config
# @nestjs/config
# @nestjs/schedule


### Verify Installation


npm ls @elsikora/nestjs-typeorm-aws-connector

💡 Usage

Prerequisites: Register Parameter Store Config Module

Before using the connector, register ParameterStoreConfigModule from @elsikora/nestjs-aws-parameter-store-config:

import { Module } from "@nestjs/common";
import { ConfigModule, ConfigService } from "@nestjs/config";
import { ENamespace, ParameterStoreConfigModule } from "@elsikora/nestjs-aws-parameter-store-config";

@Module({
  imports: [
    ConfigModule.forRoot(),
    ParameterStoreConfigModule.registerAsync({
      imports: [ConfigModule],
      inject: [ConfigService],
      useFactory: (configService: ConfigService) => ({
        application: configService.getOrThrow<string>("APPLICATION"),
        config: { region: configService.getOrThrow<string>("AWS_REGION") },
        environment: configService.getOrThrow<string>("ENVIRONMENT"),
        instanceName: "my-api",
        namespace: ENamespace.AWS_ECS_FARGATE,
        shouldDecryptParameters: true,
      }),
    }),
  ],
})
export class AppModule {}

Basic Usage: Static Registration

import { Module } from "@nestjs/common";
import { TypeOrmModule } from "@nestjs/typeorm";
import {
  TypeOrmAwsConnectorModule,
  TypeOrmAwsConnectorService,
} from "@elsikora/nestjs-typeorm-aws-connector";
import { UserEntity } from "./entities/user.entity";

@Module({
  imports: [
    // Register the connector with your entities
    TypeOrmAwsConnectorModule.register({
      entities: [UserEntity],
    }),
    // Wire it into TypeOrmModule
    TypeOrmModule.forRootAsync({
      imports: [TypeOrmAwsConnectorModule],
      inject: [TypeOrmAwsConnectorService],
      useFactory: async (connector: TypeOrmAwsConnectorService) =>
        connector.getTypeOrmOptions(),
    }),
  ],
})
export class DatabaseModule {}

Custom SSM Lookups

Override where specific fields are resolved from in Parameter Store:

import { ENamespace } from "@elsikora/nestjs-aws-parameter-store-config";
import { TypeOrmAwsConnectorModule } from "@elsikora/nestjs-typeorm-aws-connector";

TypeOrmAwsConnectorModule.register({
  entities: [UserEntity],
  ssmLookupDefaults: {
    instanceName: "my-api",
    namespace: ENamespace.AWS_ECS_FARGATE,
  },
  ssmLookups: {
    secretId: {
      instanceName: "database",
      namespace: ENamespace.AWS_SECRETS_MANAGER,
      path: ["secret-id"],
    },
    host: {
      instanceName: "aurora-postgres",
      namespace: ENamespace.AWS_RDS,
      path: ["host"],
    },
    port: {
      instanceName: "aurora-postgres",
      namespace: ENamespace.AWS_RDS,
      path: ["port"],
    },
  },
});

Local Development: Raw Value Overrides

Bypass AWS entirely for local development:

import { EDatabaseType } from "@elsikora/nestjs-typeorm-aws-connector";

TypeOrmAwsConnectorModule.register({
  entities: [UserEntity],
  host: "127.0.0.1",
  port: 5432,
  username: "local-user",
  password: "local-password",
  databaseName: "mydb",
  type: EDatabaseType.POSTGRES,
});

Enabling Credential Rotation

Enable automatic credential rotation for long-running services:

TypeOrmAwsConnectorModule.register({
  entities: [UserEntity],
  rotation: {
    isEnabled: true,
    intervalMs: 3_600_000, // Rotate every hour
  },
});

The rotation service will:

  1. Validate current connection health
  2. Fetch fresh credentials from AWS Secrets Manager
  3. Create and initialize a replacement DataSource with the updated credentials
  4. Verify the replacement connection with a SELECT 1 query
  5. Promote the replacement driver for future query runners without destroying the live DataSource
  6. Dispose the previous pool only after query runners created before the promotion are released
  7. Attempt emergency recovery after 3 consecutive failures

Rotation is intended for long-lived services. For one-shot jobs, migrations, or explicit CLI tasks, keep rotation.isEnabled disabled so the connector does not register a background interval.


Async Registration with Factory

TypeOrmAwsConnectorModule.registerAsync({
  imports: [ConfigModule],
  inject: [ConfigService],
  useFactory: (configService: ConfigService) => ({
    entities: [UserEntity],
    rotation: {
      isEnabled: configService.get<boolean>("DB_ROTATION_ENABLED", false),
      intervalMs: configService.get<number>("DB_ROTATION_INTERVAL", 3_600_000),
    },
  }),
});

Multiple Database Modules In One App

Register the connector separately inside each Nest database module that owns a specific TypeORM connection. The connector module is scoped to that module registration, so multiple connector instances can safely coexist in one application.

import { getDataSourceToken } from "@nestjs/typeorm";

TypeOrmAwsConnectorModule.registerAsync({
  dataSourceToken: getDataSourceToken("provider"),
  imports: [ConfigModule],
  inject: [ConfigService],
  useFactory: (configService: ConfigService) => ({
    entities: [ProviderEntity],
  }),
});

Use dataSourceToken when the connector's RotatorService should bind to a named TypeORM DataSource instead of the default connection token.


Value Resolution Priority

For each configuration field, values are resolved in this order:

  1. Raw value override (provided directly in config)
  2. SSM Parameter Store lookup (via structured lookup)
  3. Built-in default (only for optional tuning fields like poolSize, connectionTimeoutMs)

Required fields (host, port, databaseName, type, secretId) throw explicit errors if not resolvable.

🛣 Roadmap

| Task / Feature | Status | |---|---| | Dual ESM/CJS module output | ✅ Done | | AWS Secrets Manager credential resolution | ✅ Done | | Automatic credential rotation with staged driver promotion | ✅ Done | | Emergency recovery after consecutive rotation failures | ✅ Done | | Split-source configuration model (infra vs app namespaces) | ✅ Done | | Raw value overrides for local development | ✅ Done | | Async module registration with factory pattern | ✅ Done | | Semantic release with prerelease channel | ✅ Done | | Support for additional database types (e.g., MariaDB, CockroachDB) | 🚧 In Progress | | Connection pool monitoring and metrics export | 🚧 In Progress | | Read replica support with separate SSM lookups | 🚧 In Progress | | Integration test suite with LocalStack | 🚧 In Progress |

❓ FAQ

❓ Frequently Asked Questions

Q: Do I need AWS credentials to use this locally? A: No! Use raw value overrides to bypass AWS entirely during local development. Set host, port, username, password, databaseName, and type directly in the config.

Q: Which databases are supported? A: Currently PostgreSQL (EDatabaseType.POSTGRES) and MySQL (EDatabaseType.MYSQL). The type field is resolved from SSM or set directly.

Q: What happens if AWS Secrets Manager is unreachable during rotation? A: The rotation service catches the error, increments a failure counter, and logs it. After 3 consecutive failures, it attempts an emergency recovery with a fresh replacement connection. Failed replacements are discarded, and the currently promoted pool stays in place until a later rotation succeeds.

Q: Can I use this without @elsikora/nestjs-aws-parameter-store-config? A: No. The connector depends on ParameterStoreConfigService.get() for SSM lookups. You must register ParameterStoreConfigModule first. However, if you provide raw values for all fields, SSM lookups won't actually be invoked.

Q: How does the split-source model work? A: Infrastructure-owned fields like host, port, and secretId default to canonical AWS namespaces (e.g., aws-rds/aurora-postgres). Application-owned fields like poolSize and connectionTimeoutMs use your app's namespace (e.g., aws-ecs-fargate/my-api). You can override any lookup.

Q: Is this compatible with NestJS v8? A: Yes. The peer dependency accepts @nestjs/common ^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0.

Q: How do I disable credential rotation? A: Don't set the rotation config, or explicitly set rotation.isEnabled: false. The RotatorService will skip interval registration entirely. This is the recommended mode for one-shot jobs, migrations, and other short-lived processes.

Q: What's the default rotation interval? A: 1 hour (3,600,000 ms). Override it via rotation.intervalMs or the SSM path typeorm/rotation/interval-ms.

🔒 License

This project is licensed under MIT.

🙏 Acknowledgments

  • NestJS — The progressive Node.js framework that makes building server-side applications a joy
  • TypeORM — The ORM that powers the database layer with decorator-based entity definitions
  • AWS SDK for JavaScript v3 — Modular AWS SDK used for SSM and Secrets Manager client operations
  • @elsikora/nestjs-aws-parameter-store-config — The Parameter Store config module that provides the structured lookup foundation
  • Semantic Release — Automated versioning and changelog generation
  • Rollup — Module bundler powering the dual ESM/CJS build output
  • Built with ❤️ by ElsiKora