Skip to main content

Overview

The DatabaseFactory creates database resources with type-safe configurations. It supports Aurora (Serverless v2 clusters), RDS instances, Global Aurora, and DynamoDB tables.
For S3 storage buckets, use the StorageFactory instead.

Basic Usage

import { App, DatabaseFactory } from "@fjall/components-infrastructure";

const app = App.getApp("myapp");

const database = app.addDatabase(
  DatabaseFactory.build("Main", {
    type: "Aurora",
    databaseName: "myapp",
  }),
);

Database Types

Aurora

Aurora Serverless v2 cluster running PostgreSQL or MySQL:
const db = app.addDatabase(
  DatabaseFactory.build("Main", {
    type: "Aurora",
    databaseName: "myapp",
    databaseEngine: "postgresql", // or "mysql"
  }),
);
Features:
  • Serverless v2 writer and optional read replicas
  • Capacity scales automatically with load
  • High availability across Availability Zones
  • Automatic backups with snapshot removal policy

RDS Instance

Traditional database instance for predictable workloads:
const db = app.addDatabase(
  DatabaseFactory.build("Main", {
    type: "Instance",
    databaseName: "myapp",
    databaseEngine: "postgresql",
    instanceType: "t4g.micro",
  }),
);
Features:
  • Fixed instance size
  • Lower baseline cost for small workloads
  • Free tier eligible (t4g.micro)

Global Aurora

Multi-region database for global applications:
const db = app.addDatabase(
  DatabaseFactory.build("Main", {
    type: "GlobalAurora",
    databaseName: "myapp",
    primaryRegion: "us-east-1",
    secondaryRegions: ["eu-west-1", "ap-southeast-2"],
  }),
);
Features:
  • Cross-region replication
  • Low-latency global reads
  • Automatic failover

DynamoDB

Serverless NoSQL database:
const cache = app.addDatabase(
  DatabaseFactory.build("Cache", {
    type: "DynamoDB",
    partitionKey: { name: "id", type: "S" },
    sortKey: { name: "timestamp", type: "N" },
  }),
);
Features:
  • Serverless (pay per request)
  • Single-digit millisecond latency
  • Automatic scaling
  • Global tables support

Configuration Parameters

Common Parameters (Relational)

ParameterTypeDescriptionDefault
type"Aurora" | "Instance" | "GlobalAurora"Database typeRequired
databaseNamestringDatabase nameRequired
databaseEngine"postgresql" | "mysql"Database engine (simple string)"postgresql"
engineIClusterEngine | IInstanceEngineCDK engine object (advanced override)-
portnumberDatabase portEngine default
monitoringIntervalnumberEnhanced monitoring interval (seconds)0 (disabled)
preferredMaintenanceWindowstringMaintenance window (e.g., “Sun:23:00-Mon:01:00”)-
Use databaseEngine for simple string-based configuration. Use engine only when you need to pass a CDK engine object with custom parameters.

Aurora Parameters

ParameterTypeDescriptionDefault
databaseEngine"postgresql" | "mysql"Database engine"postgresql"
deletionProtectionbooleanPrevent accidental deletiontrue in prod
backupRetentionnumberBackup retention in days14 (Standard), 30 (Resilient), 35 (Enterprise)
databaseInsightsobject | falseDatabase Insights config, or false to disable-
databaseInsights.retentionPeriodnumberRetention days (7, 31, 62, etc.)7
writerobjectWriter instance configurationAuto
readersobject[] | falseRead replica configurations, or false to disable[]
proxyobject | falseRDS Proxy configuration, or false to disable-
credentialsobjectUsername and rotation configAuto
encryptionobjectStorage encryption with KMSDefault key
publiclyAccessiblebooleanAllow public access (dev only)false
allowedIpCidrstringCIDR for public access-
snapshotIdentifierstringRestore from snapshot-

Instance Parameters

ParameterTypeDescriptionDefault
instanceTypestringInstance type"t4g.large"
allocatedStoragenumberStorage in GB20
multiAzbooleanEnable Multi-AZfalse
backupRetentionnumberBackup retention in days14 (Standard), 30 (Resilient), 35 (Enterprise)
databaseInsightsobjectDatabase Insights config-
readReplicaobjectRead replica configuration-
proxyobjectRDS Proxy configuration-
publiclyAccessiblebooleanAllow public access (dev only)false
snapshotIdentifierstringRestore from snapshot-

DynamoDB Parameters

ParameterTypeDescriptionDefault
partitionKey{ name, type }Partition key definitionRequired
sortKey{ name, type }Sort key definition-
billingMode"PAY_PER_REQUEST" | "PROVISIONED"Billing mode"PAY_PER_REQUEST"
readCapacitynumberRead capacity units (provisioned)-
writeCapacitynumberWrite capacity units (provisioned)-
globalSecondaryIndexesarrayGSI definitions-
timeToLiveAttributestringTTL attribute name-
pointInTimeRecoverybooleanEnable PITRtrue
stream"NEW_IMAGE" | "OLD_IMAGE" | "NEW_AND_OLD_IMAGES" | "KEYS_ONLY"DynamoDB Streams view type-
encryption"AWS_OWNED" | "AWS_MANAGED" | "CUSTOMER_MANAGED"Table encryption mode"AWS_OWNED"
removalPolicy"DESTROY" | "RETAIN" | "SNAPSHOT"What happens on delete"RETAIN"

Common Patterns

Production Aurora

const db = app.addDatabase(
  DatabaseFactory.build("Production", {
    type: "Aurora",
    databaseName: "myapp",
    databaseEngine: "postgresql",
    databaseInsights: { retentionPeriod: 31 },
    deletionProtection: true,
  }),
);

Development Database

const db = app.addDatabase(
  DatabaseFactory.build("Dev", {
    type: "Instance",
    databaseName: "myapp_dev",
    instanceType: "t4g.micro", // Free tier eligible
  }),
);

Cache Table

const cache = app.addDatabase(
  DatabaseFactory.build("Cache", {
    type: "DynamoDB",
    partitionKey: { name: "key", type: "S" },
    timeToLiveAttribute: "expiresAt",
  }),
);

Session Store

const sessions = app.addDatabase(
  DatabaseFactory.build("Sessions", {
    type: "DynamoDB",
    partitionKey: { name: "sessionId", type: "S" },
    timeToLiveAttribute: "expiresAt",
    pointInTimeRecovery: true,
  }),
);

Accessing Database Information

Relational Databases

const db = app.addDatabase(
  DatabaseFactory.build("Main", {
    type: "Aurora",
    databaseName: "myapp",
  }),
);

// Get connection info
const host = db.getHostEndpoint();
const port = db.getHostPort();
const name = db.getDatabaseName();

// Get credentials (Secret)
const credentials = db.getCredentials();

DynamoDB

const table = app.addDatabase(
  DatabaseFactory.build("Cache", {
    type: "DynamoDB",
    partitionKey: { name: "id", type: "S" },
  }),
);

// Get table info
const tableName = table.getTableName();
const tableArn = table.getTableArn();

Connecting to Compute

Lambda with Database

const db = app.addDatabase(
  DatabaseFactory.build("Main", { type: "Aurora", databaseName: "myapp" }),
);

app.addCompute(
  ComputeFactory.build("Api", {
    type: "lambda",
    deployment: "code",
    handler: "api.handler",
    connections: [db],
  }),
);

ECS with Database

const db = app.addDatabase(
  DatabaseFactory.build("Main", { type: "Aurora", databaseName: "myapp" }),
);

app.addCompute(
  ComputeFactory.build("Api", {
    type: "ecs",
    services: [
      {
        name: "api",
        capacityProvider: "FARGATE",
        containers: [
          {
            environment: {
              DATABASE_HOST: db.getHostEndpoint(),
              DATABASE_NAME: db.getDatabaseName(),
            },
            secretsImport: {
              DATABASE_PASSWORD: db.getCredentials().getImport("password"),
            },
          },
        ],
      },
    ],
    connections: [db],
  }),
);

Granting Access

Relational Databases

Access is automatically granted when using connections. For manual grants:
db.grantConnect(lambdaFunction);

DynamoDB

// Read only
table.grantReadData(lambdaFunction);

// Write only
table.grantWriteData(lambdaFunction);

// Read/Write
table.grantReadWriteData(lambdaFunction);

// Full access
table.grantFullAccess(lambdaFunction);

Security

Automatic Security Features

  • Encryption at rest: All databases encrypted by default
  • Encryption in transit: SSL/TLS enforced
  • Secrets Manager: Credentials stored securely
  • VPC isolation: Databases in private subnets
  • Security groups: Automatic least-privilege rules

Database Insights

const db = app.addDatabase(
  DatabaseFactory.build("Main", {
    type: "Aurora",
    databaseName: "myapp",
    databaseInsights: {
      retentionPeriod: 31, // days (7, 31, 62, 93, 124, 155, 186, 217, 248, 279, 310, 341, 372, 403, 434, 465, 496, 527, 558, 589, 620, 651, 682, 713, 731)
    },
  }),
);

Best Practices

  1. Use Aurora Serverless for variable workloads
  2. Use Instance for predictable, small workloads
  3. Enable Database Insights in production
  4. Use DynamoDB for key-value and session data
  5. Use connections for automatic IAM and security group setup
  6. Enable deletion protection in production

Next Steps

Storage Factory

Create S3 buckets for file storage

Compute Factory

Deploy Lambda and ECS compute resources

Payload Pattern

Full-stack Payload CMS deployment

Standard Pattern

Production web application pattern