Provisioning datastores
Provision RDS, Cloud SQL, Azure DB, ElastiCache, Memorystore, and Azure Cache for Redis; or adopt existing ones.
ZopDay provisions and adopts cloud-managed datastores across all three clouds. Two flows: Create (provision new) and Adopt (wire an existing datastore into ZopDay without modifying it). Both end up as a deployment-attachable resource your services can connect to via service connections.
Supported datastores
| Family | AWS | GCP | Azure |
|---|---|---|---|
| Postgres | RDS PostgreSQL | Cloud SQL PostgreSQL | Azure Database for PostgreSQL Flexible Server |
| MySQL | RDS MySQL | Cloud SQL MySQL | Azure Database for MySQL Flexible Server |
| Redis | ElastiCache for Redis | Memorystore for Redis | Azure Cache for Redis |
Day-one provider parity. Other engines (Mongo, Cassandra, etc.) are supported via the BYO Adopt flow but not via Create.
Create flow
Provisioning → New provisioning job → Datastore. Walks through:
Family + engine
Postgres / MySQL / Redis. Each has an engine version dropdown (defaults to the latest supported major version available on the cloud).
Cloud account + region + network
Pick the connected cloud account and region. ZopDay defaults the datastore into the private subnet of the cluster’s VPC if a cluster is selected; otherwise you pick a VPC explicitly.
Sizing
Instance class (Small / Medium / Large presets or custom), storage GB, IOPS, Multi-AZ on/off, automated backup retention days.
Production presets enable Multi-AZ and 7-day backups by default. Dev presets disable Multi-AZ and use 1-day backups for cost.
Credentials
ZopDay generates a strong root password automatically and stores it in your cloud’s secret manager. AWS Secrets Manager / GCP Secret Manager / Azure Key Vault. The password is never stored in ZopDay’s database: only the secret manager path (ARN / URI) is.
You can override the username if your org has naming conventions. The password is always auto-generated.
Review + create
Estimated monthly cost based on the chosen tier, expected storage, and backup retention. Click create.
Create takes 5–15 minutes depending on the cloud and tier; the slowest step is the cloud-side instance provisioning itself (RDS / Cloud SQL / Azure DB managed-service create calls block on the engine being ready).
If a create fails, the job is marked failed in the Provisioning Jobs view with the failing step and error. Common causes are quota limits, insufficient permissions, a missing or invalid subnet group / network, or a name conflict with an existing instance. Fix the cause and retry; the job resumes from the last successful step.
Adopt flow
For datastores you already own and want to wire into ZopDay without changing anything cloud-side.
Provisioning → New provisioning job → Datastore → toggle to Adopt existing mode.
Pick the existing instance
ZopDay lists every datastore visible to the connected cloud account in the chosen region. Pick the one you want to adopt.
Provide credentials
Paste the connection URI (or hostname + port + username); credentials go to your cloud’s secret manager via
StoreDatastoreCredentialsgRPC. ZopDay stores only the secret manager reference.Confirm metadata
ZopDay shows what it discovered about the datastore (engine, version, tier, network) and asks you to confirm. No cloud API mutations happen; this is pure ingest.
Apply
The adopted datastore appears in your inventory and is available for service connections.
For adopted datastores:
- Teardown is a no-op: disconnecting an adopted datastore from ZopDay only removes ZopDay’s pointer. The underlying datastore stays running, untouched.
- Credentials can be rotated via the same secret manager flow; ZopDay re-reads from the secret manager on every connection refresh.
- Sizing changes are out of scope: ZopDay never modifies adopted datastores. Resize them through your normal cloud workflow.
Where credentials live
Credentials handling is the same for both Create and Adopt:
| Cloud | Secret manager |
|---|---|
| AWS | Secrets Manager |
| GCP | Secret Manager |
| Azure | Key Vault |
ZopDay stores only the secret reference (ARN / URI), not the password itself. The secret value is read at runtime by your application’s pod, using whichever cloud identity is bound to its service account. IRSA on AWS, Workload Identity on GCP, AAD federated identity on Azure.
This means ZopDay never has the password. If you regenerate it via AWS Secrets Manager directly, ZopDay’s reference still works because the reference is to the secret path, not the secret value.
Service connections to datastores
Once a datastore exists in your inventory (either created or adopted), wire a deployment to it via a service connection with injectedVar:
POST /orgs/{orgID}/environments/{envID}/deployments/connections{ "sourceDeploymentId": "<api-server-uuid>", "targetDeploymentId": "<datastore-uuid>", "injectedVar": "DATABASE_URL"}ZopDay injects DATABASE_URL on the consumer’s pod as a reference to the secret manager path, not the password itself. Your code reads the value at runtime via the bound cloud identity. See Service connections.
Why ZopDay never mutates customer DBs
Even when ZopDay created the datastore, it does not change its tier, replica count, or backup policy after creation. The rule from CLAUDE.md §12:
ZopDay never mutates customer-managed databases via the provisioner. DB tier changes and replica scaling are the customer’s DBA team’s call.
This is enforced in code: the pause template’s allowlist explicitly excludes rds*, aurora*, cloudsql*, elasticache*, azure-sql, postgres*, mysql*. The provisioner refuses pause/delete operations on these resource types.
If you want sizing recommendations on a database, attach it to an event readiness plan as a monitor-only target. ZopDay computes the suggested tier (with connection-pool math) and surfaces it; you implement it through your DBA workflow.
What “create” actually does on each cloud
For transparency about the cloud API calls:
| Cloud | Datastore | API call |
|---|---|---|
| AWS | RDS Postgres | CreateDBInstance with private subnet group, KMS-encrypted storage |
| AWS | ElastiCache | CreateReplicationGroup (cluster mode disabled by default; on for Large preset) |
| GCP | Cloud SQL | instances.insert with privateNetwork set to the VPC, automatic SSD storage growth |
| GCP | Memorystore | instances.create with private service access |
| Azure | Postgres Flexible | flexibleServers.create in private DNS zone mode |
| Azure | Azure Cache for Redis | redis.create with VNet binding (Premium tier) or private endpoint (Standard tier) |
All instances are created with encryption-at-rest enabled and TLS-required connections.
Cost preview
The cost estimate is the sum of:
- Hourly instance cost × 730 (monthly hours)
- Storage GB × per-GB rate
- IOPS provisioned × per-IOPS rate (where applicable)
- Backup storage × retention days × per-GB rate
- Multi-AZ multiplier (typically 2× the base instance cost)
It’s an estimate with the isEstimated: true badge. Actuals diverge based on storage growth, IOPS bursts, and inter-AZ traffic; all of which we can’t predict from provisioning config alone.
Teardown
DELETE /provisioning-jobs/{id} on a created datastore:
- Submits the cloud delete call (for Postgres / MySQL, with skip-final-snapshot=false by default, so a final snapshot is taken; Redis engines do not take a final snapshot the same way)
- Deletes the secret in the cloud secret manager
- Removes the inventory row
- Removes the service connections that pointed at it
For adopted datastores, teardown is a no-op (per the contract above).