Overview
RdsInstance provisions a managed PostgreSQL database instance with Multi-AZ deployment, storage encryption, automated backups, IAM database authentication, and optional RDS Proxy pooling and read replicas.
Pick it over Aurora when you want predictable, fixed-size capacity and a lower floor price. Aurora suits variable or bursty workloads.
Add a database from the CLI
fjall add database:
Add
--tier <name> to expand a preset into the emitted properties, where the name is tinkerer, lightweight, standard, resilient, or enterprise. On fjall add database the tier flag also requires --type, because each tier describes each database type differently.
Import the construct
Basic usage
instanceType takes the bare class.size form (t4g.medium, r7g.large), not the db.-prefixed form. The construct passes the value straight to new InstanceType(...), so a db. prefix produces an invalid instance class.Configuration options
Core properties
The instance identifier is derived from the construct ID in kebab case, so
ProductionDatabase becomes production-database. It is not settable through props.
Instance sizing
When Fjall provisions a database through an application tier, the instance type comes from the tier preset:
t4g.micro (Tinkerer), t4g.small (Lightweight), t4g.large (Standard), r7g.large (Resilient), r7g.xlarge (Enterprise). Using the construct directly, set instanceType yourself.Backup and maintenance
backupRetention must be a whole number of days. A fractional Duration throws at synth.
Security
Snapshot restore
Optional features
Ports and connectivity
The listener port comes from the engine family, so a PostgreSQL instance listens on5432 unless you set port explicitly. The construct opens a self-referencing ingress rule on that port and exposes a Connections object with the same default.
Grant access with the default port rather than a literal, so the wiring stays correct if the port or the proxy changes:
Security
Encryption
Storage encryption is always on. The default key is the AWS-managed RDS key. Passencryption.storageKey to request a customer-managed key (CMK), which Fjall creates and retains beyond the stack so final snapshots stay restorable.
IAM database authentication
IAM authentication is on by default. It costs nothing and grants nothing until you callgrantIamConnect, and password authentication keeps working alongside it.
rds-db:connect to the exact dbuser:<dbiResourceId>/<username> ARN. Calling it on an instance that opted out with iamAuthentication: false throws at synth.
Credentials
Fjall generates a Secrets Manager secret named<ConstructId>/credentials holding the master username and a generated password. Read it with getCredentials() and import individual fields into a container:
{} accepts the 30-day default:
Network placement
Instances land in private subnets with egress. SettingpubliclyAccessible: true moves them to public subnets, which is how the Tinkerer tier runs without a NAT gateway.
High availability
Multi-AZ is on by default. SetmultiAz: false to opt out, which the Tinkerer and Lightweight presets do.
- Automatic failover, typically in 1 to 2 minutes
- Synchronous replication to the standby
- Patching applied to the standby first
- Higher durability
RDS Proxy
Pass aProxyConfig object to add connection pooling. Fields: requireTLS, maxConnections, maxIdleConnections, connectionBorrowTimeout (seconds), vpcSubnets.
getHostEndpoint() returns the proxy endpoint and database.connections targets the proxy security group. requireTLS defaults to true and the borrow timeout defaults to 120 seconds. The proxy name is the kebab-case construct ID plus -proxy.
Read replicas
Pass aReadReplicaConfig object to add one replica. Fields: instanceType, availabilityZone. Pass {} to inherit the primary’s instance type.
-read-replica. Replication is asynchronous, so replica reads lag the primary.
A deletion waiter custom resource holds stack deletion until the primary reports available, because deleting a replica puts the primary into modifying and the final snapshot would otherwise fail.
Database Insights
Database Insights (formerly Performance Insights) is on in standard mode by default. Pass a config object to change the mode, orfalse to switch it off. Fields: mode ("standard" or "advanced"), encryptionKey.
Backups and restore
Automated backups run daily in the backup window and support point-in-time recovery. Transaction logs are captured continuously. Automated backups are retained when the instance is deleted, and the removal policy takes a final snapshot on stack deletion.Restoring from a snapshot
The password reset applies only to restores performed through infrastructure code (
snapshotIdentifier). Restores performed through AWS Backup (fjall restore rds) run outside CloudFormation and keep the snapshot-era password. Reconcile the credentials, then run fjall rollout <app> so running containers pick up the new values. See fjall restore.Methods
Two properties are also public:
connections (a CDK Connections object) and databaseSecurityGroup.
Complete example
Cost optimisation
Instance sizing
*Rough on-demand estimates for
us-east-1, single-AZ, storage excluded. Multi-AZ roughly doubles the instance charge. Check the AWS pricing page for current rates.
Ways to cut spend
- Use Graviton instance families (
t4g,m7g,r7g) for better price-performance. - Buy Reserved Instances for steady 1 to 3 year workloads.
- Right-size from CloudWatch metrics rather than from the tier default.
- Consider Aurora Serverless v2 for spiky or intermittent traffic.
- Start
allocatedStoragesmall and let autoscaling raise it, rather than over-provisioning. - Switch
databaseInsightstofalseon non-production instances that nobody inspects.
Best practices
- Keep Multi-AZ on for production, which is the default.
- Use memory-optimised types (
r7g) for production write workloads. - Grant network access with
allowDefaultPortFrom, not a hardcoded port. - Read credentials from the generated secret, never from a checked-in value.
- Use
grantIamConnectfor application roles so no long-lived password is needed. - Test a restore before you rely on backups.
- Wire
alertsTopicso alarm notifications reach a real inbox.
Limitations
securityGroupIdsandclusterIdentifierare accepted but ignored.- The read replica inherits almost everything from the primary. Only
instanceTypeandavailabilityZoneare configurable. - RDS Proxy cannot listen on a custom port, so it always uses the engine default.
- Deletion protection is on by default, so a stack destroy needs it turned off first.
- The removal policy takes a final snapshot, so destroying a stack leaves a snapshot (and its CMK, when one was requested) behind.
- Cross-region failover is not automatic. Use Global Aurora for that.
- Read replicas lag the primary because replication is asynchronous.
- Maintenance windows cause brief downtime on single-AZ instances.
Next Steps
Database Factory
Provision databases through the Fjall factory API.
RDS Aurora
Scale to an Aurora cluster with serverless and global options.
RDS Free Tier
Run a free-tier-eligible PostgreSQL instance during your first 12 months.
Secrets Manager
Manage database credentials and rotation.