Overview
DatabaseFactory builds database resources from a type-safe props object. Each type is a separate overload, so TypeScript narrows the available options as soon as you set type.
For S3 storage buckets, use the StorageFactory instead.
Basic Usage
Database Types
Aurora
Aurora Serverless v2 cluster running PostgreSQL or MySQL:- Serverless v2 writer plus one reader by default. Set
readers: falsefor a single-instance cluster. - Storage encrypted at rest, SSL enforced through the parameter group.
- Deletion protection on, and the removal policy defaults to
SNAPSHOT. - Enhanced Monitoring on at a one-minute interval, and Database Insights on in standard mode.
RDS Instance
A single database instance for predictable workloads:- Fixed instance size, with storage autoscaling to 500 GiB.
- Multi-AZ on by default. Pass
multiAz: falsefor a single-AZ instance. - IAM database authentication on by default, alongside password auth.
t4g.microis free-tier eligible.
Global Aurora
Multi-region Aurora cluster:- Cross-region replication with low-latency reads in each secondary region.
- Managed failover to a secondary region.
primaryRegionis required. Synth fails without it.
DynamoDB
Serverless key-value and document store:- On-demand billing by default (
PAY_PER_REQUEST). - Point-in-time recovery on by default.
- Encrypted with the AWS-managed
aws/dynamodbKMS key by default, which bills KMS API requests.
The factory does not configure DynamoDB global tables. For a multi-region relational store, use
GlobalAurora.ClickHouse
Single-node ClickHouse analytics database on EC2 with an ECS task, an EBS data volume and an S3 cold tier:- Database name is fixed at
analytics. schemaAdminis required. Itsnamemust match^[a-z][a-z0-9_]*$and must not carry the reservedfjallprefix. Itsprofilenames a key inprofiles, or one of the four defaults:high_throughput_ingest,audit_append,read_only,ddl_admin.- Scheduled
OPTIMIZE TABLE FINALevery 6 hours, plus a daily backup to S3 at 03:00 UTC that restores what it wrote into a scratch database to verify it. storageGbgrows only. EBS refuses to shrink a volume and permits one modification per volume per 6 hours.
Configuration Parameters
Defaults the backup tier owns
Four defaults on this page read the application’s backup tier (App.getApp(name, { backup: { tier } })) rather than a fixed value. An application with no backup tier, or backup: false, gets the Standard column. Setting the parameter on the resource overrides the tier for that resource.
fjall destroy switches deletion protection off on every database, table and load balancer in a stack before deleting it, so a protected table never wedges a destroy; it only stops a delete that nobody asked for.
Shared (Aurora, Instance, GlobalAurora)
DatabaseInsightsConfig takes two fields:
CredentialsConfig takes username and an opt-in secretRotation block. Rotation resources are created only when you pass an object. secretRotation: { automaticallyAfterDays: 30 } is the scaffolded form.
Cluster (Aurora and Global Aurora)
AuroraReadersConfig takes count (default 1), or a per-reader instances array, plus defaultEnableDatabaseInsights. count and instances are mutually exclusive.
Aurora only
Global Aurora only
Global Aurora does not accept
removalPolicy, engineVersion, or the serverless v2 capacity props.
Instance
ReadReplicaConfig takes instanceType and availabilityZone. The replica inherits the primary’s instanceType when unset.
monitoringInterval and preferredMaintenanceWindow are cluster-only props. Instance databases apply the same defaults but expose no override. Aurora and Global Aurora ignore instanceType because their instances are serverless v2.
DynamoDB
Attribute types are
"S" (string), "N" (number) and "B" (binary). encryption and deletionProtection follow the backup tier unless set here.
AWS_MANAGED encrypts with the AWS-managed aws/dynamodb KMS key and bills KMS API requests. AWS_OWNED uses an AWS-owned key at no cost. CUSTOMER_MANAGED encrypts with the stack’s shared customer-managed key (one key per stack, created on first use, about $1–3 a month).ClickHouse
Common Patterns
Production Aurora
Development Database
Single-Instance Aurora
Drop the default reader when one writer is enough:Scale-to-Zero Aurora
Session Store
Accessing Database Information
Relational Databases
getConnectionString() returns <scheme>://<host>:<port>/<dbname> and deliberately excludes credentials. Secrets Manager references cannot be interpolated at synth time without baking plaintext into the CloudFormation template. Compose the final URL at runtime from the injected user and password.DynamoDB
ClickHouse
Connecting to Compute
Lambda
connections sits at the root of the Lambda props. The factory injects the application VPC automatically when connections are present.
ECS
connections sits on each service inside services[], not at the compute root. Each service gets its own least-privilege grants.
Granting Access
Relational Databases
connections handles security groups and IAM grants. For a manual grant:
grantIamConnect issues short-lived rds-db:connect tokens for a named database user, so the grantee never reads a stored password. It is Instance-only and throws at synth on Aurora or Global Aurora:
DynamoDB
Schema Migrations
Amigrations block turns the database into a schema-version gate. Every container of every service whose connections include the database receives EXPECTED_SCHEMA_VERSION at synth time, and eligible services gain a fjall-schema-gate container that verifies the live schema before any application container starts.
tool: "custom" takes the same dir plus a versionResolver: (dir: string) => string. ClickHouse uses its own block with dir and an optional versionResolver, and no tool field. See Deployment safety for the full gate behaviour.
Security
Every database the factory builds arrives with:- Encryption at rest. Storage encryption on for relational types, KMS encryption for DynamoDB tables.
- Encryption in transit.
rds.force_ssl=1for PostgreSQL,require_secure_transport=ONfor MySQL. - Secrets Manager credentials. Master credentials generated into a secret, never rendered into the template.
- VPC isolation. Private subnets unless
publiclyAccessibleis set. - Least-privilege security groups. Rules created per connected service, not per cluster.
Best Practices
- Use Aurora for variable workloads, Instance for predictable small ones.
- Set
readers: falseon non-production Aurora clusters to halve the instance bill. - Set
multiAz: falseanddeletionProtection: falseon development instances. - Set
databaseInsights: { mode: "advanced" }in production for 15 months of query history. - Declare
connectionsrather than hand-wiring security groups and IAM. - Declare
migrationsso a schema mismatch stops the deployment instead of crash-looping.
Next Steps
Aurora Reference
Aurora cluster options in depth
DynamoDB Reference
Table, index and stream configuration
Compute Factory
Deploy Lambda and ECS compute resources
Deployment Safety
Schema gates and destructive-change consent