Relational Database
Managed relational-database control-plane emulation for RDS/Aurora, Redshift, Azure SQL, PostgreSQL/MySQL Flexible Server, and Cloud SQL
aws RDSazr Azure SQLgcp Cloud SQL
Emulates the control plane of managed relational databases — the API that provisions, stops, snapshots, and restores an RDS/Cloud SQL/Azure SQL instance. It models the instance lifecycle, Aurora-style clusters and their member instances, and snapshot/restore, but not the SQL surface itself: there's no query engine behind the endpoint. Instances move through realistic states (creating → available → stopped → deleting) so your infra code sees the same transitions it would in production.
Reach for it in tests when your provisioning or IaC code creates a DB instance, waits for it to become available, stops it, or snapshots and restores it — so you can exercise those lifecycle paths without spinning up real (and slow, and billed) instances. For NoSQL stores (DynamoDB, Cosmos DB, Firestore), see Database instead.
| Provider | Service | SDK-compat | Driver |
|---|---|---|---|
| AWS | RDS (+ Aurora clusters, Neptune & DocumentDB engines) | ✓ Live | aws.RDS |
| AWS | Redshift (cluster + snapshots) | ✓ Live | aws.Redshift |
| Azure | SQL Database (logical server + databases) | ✓ Live | azure.SQL |
| Azure | PostgreSQL Flexible Server | ✓ Live | azure.PostgresFlex |
| Azure | MySQL Flexible Server | ✓ Live | azure.MySQLFlex |
| GCP | Cloud SQL (MySQL / PostgreSQL / SQL Server) | ✓ Live | gcp.CloudSQL |
Drive it with the real SDK#
The recommended path is to point the real SDK at the SDK-compat server. This provisions a standalone Postgres instance, an Aurora cluster, then stops the instance — the same lifecycle calls your infra code makes, against an in-memory control plane:
import (
"github.com/aws/aws-sdk-go-v2/service/rds"
"github.com/aws/aws-sdk-go-v2/service/rds/types"
"github.com/stackshy/cloudemu/v2"
awsserver "github.com/stackshy/cloudemu/v2/server/aws"
)
cloud := cloudemu.NewAWS()
ts := httptest.NewServer(awsserver.New(awsserver.Drivers{
RDS: cloud.RDS,
Redshift: cloud.Redshift,
}))
client := rds.NewFromConfig(cfg, func(o *rds.Options) {
o.BaseEndpoint = aws.String(ts.URL)
})
// Standalone instance
client.CreateDBInstance(ctx, &rds.CreateDBInstanceInput{
DBInstanceIdentifier: aws.String("app-db"),
Engine: aws.String("postgres"),
DBInstanceClass: aws.String("db.t3.micro"),
AllocatedStorage: aws.Int32(20),
})
// Aurora cluster + member instance
client.CreateDBCluster(ctx, &rds.CreateDBClusterInput{
DBClusterIdentifier: aws.String("app-cluster"),
Engine: aws.String("aurora-postgresql"),
})
client.StopDBInstance(ctx, &rds.StopDBInstanceInput{
DBInstanceIdentifier: aws.String("app-db"),
})Azure servers speak ARM (armsql, armpostgresqlflexibleservers, armmysqlflexibleservers); Cloud SQL speaks the Cloud SQL Admin REST API (sqladmin/v1). See the SDK-Compat Server page for the full quick starts.
Call the driver directly#
All six services implement one driver interface, so the same calls work across every provider — handy when a test needs to run the same lifecycle assertions against more than one cloud. This creates an instance, stops it, spins up a cluster, and snapshots the instance:
import rdbdriver "github.com/stackshy/cloudemu/v2/services/relationaldb/driver"
inst, _ := aws.RDS.CreateInstance(ctx, rdbdriver.InstanceConfig{
ID: "app-db", Engine: "postgres", InstanceClass: "db.t3.micro",
})
aws.RDS.StopInstance(ctx, "app-db")
cluster, _ := aws.RDS.CreateCluster(ctx, rdbdriver.ClusterConfig{
ID: "app-cluster", Engine: "aurora-postgresql",
})
snap, _ := aws.RDS.CreateSnapshot(ctx, rdbdriver.SnapshotConfig{
ID: "app-db-snap", InstanceID: "app-db",
})Restore with RestoreInstanceFromSnapshot (or RestoreClusterFromSnapshot), passing a new ID and the snapshot ID.
Behavior & fidelity#
- Lifecycle is a real state machine. Instances and clusters move through
creating → available → modifying → starting → stopping → stopped → rebooting → deleting. Illegal transitions (e.g. stopping an already-stopped instance) return errors, so your wait-for-state code is exercised for real. - Aurora clusters own members. A cluster tracks its member instances (
Instance.ClusterID); theaurora-postgresql/aurora-mysqlengines, plus Neptune and DocumentDB, run through the RDS driver with the right ports and namespaces. - Snapshots and restore round-trip. Instance and cluster snapshots can be created, listed, deleted, and restored into new instances/clusters. Services with no cluster concept (Redshift, Flexible Server, Cloud SQL) return an error for cluster-snapshot operations; Redshift is cluster-only and errors on instance-level operations.
- Lifecycle emits metrics. State transitions push CloudWatch / Azure Monitor / Cloud Monitoring values under the correct per-engine namespace (
AWS/RDS,AWS/Redshift,Microsoft.Sql/servers/databases,cloudsql.googleapis.com, …), so metric-driven tests have data to read. - Provider quirks are preserved. Cloud SQL start/stop is emulated via
settings.activationPolicy(ALWAYS/NEVER); the Cloud SQL operations endpoint returnsDONEimmediately. - SDK-compat status — Live. All six services work through their real SDKs today: RDS/Aurora and Redshift instance/cluster/snapshot operations, Azure SQL + PostgreSQL/MySQL Flexible Server (CRUD plus
start/stop/restart), and Cloud SQL (instances CRUD,restart/restoreBackup, backup-run CRUD). See SDK-Compat for the full surface.