Overview
MongoDB Cluster deploys a highly available MongoDB replica set using Percona Server for MongoDB 8.0 into an existing GVC. The cluster provides automatic leader election, self-healing replica membership, and failover across one or more locations. An optional HAProxy workload provides a stable write endpoint that always routes to the current primary. Neither the database credentials nor the replica set keyfile are template values. Both come from secrets you create before installing, so no credential passes through Helm or lands in the release.Architecture
- MongoDB Replica Set — Multi-member cluster with keyfile authentication and automatic replica set initialization. Every member this template creates votes; only the primary accepts writes.
- HAProxy (optional, enabled by default) — Leader-routing proxy that health-checks every member and routes traffic to the current primary. Provides a stable connection endpoint that survives failover.
- Backup (optional) — Logical backup via
mongodump, restored withmongorestorethrough a port-forward tunnel.
What Gets Created
- Stateful MongoDB Workload — (
RELEASE_NAME-mongo): a MongoDB container per member per configured location, serving TCP on port27017with per-replica DNS for peer discovery. - Volume Set — (
RELEASE_NAME-mongo-vs): one persistent ext4 volume per member, mounted at/data/db, with optional capacity autoscaling. A final snapshot is taken on deletion and retained for 7 days. - Identity & Two Policies — (
RELEASE_NAME-mongo-identity,RELEASE_NAME-mongo-policy,RELEASE_NAME-mongo-gvc-policy): an identity bound to the workloads, a policy granting itrevealon exactly the two secrets you created plus the chart’s own startup scripts, and a policy grantingviewon the one GVC you install into so each member can confirm at boot that the GVC really has every location you listed. When backups are enabled, the identity also carries the cloud account binding the backup job uses to reach your bucket. - Startup Secrets — (
RELEASE_NAME-mongo-startup, andRELEASE_NAME-mongo-proxy-startupwhen the proxy is enabled): the chart’s own boot scripts. They hold no credentials. - HAProxy Workload (optional, enabled by default) — (
RELEASE_NAME-mongo-proxy): a standard workload routing traffic to the current primary. - Cron Backup Workload (optional) — (
RELEASE_NAME-mongo-backup): a scheduledmongodumpthat writes compressed archives to AWS S3 or GCS, running in one location only.
cpln workload exec, cpln logs and uninstalling all work against that GVC, and uninstalling can never delete it. Nothing runs in a GVC location you did not list in locations.Migrating from 1.x
Template versions through 1.1.1 created their own GVC, so that GVC is part of the 1.x release’s manifest. Version 2.0.0 does not declare it — and Helm deletes what a chart stops declaring.Choose the GVC for the new release
locations. See Prerequisites.Create the prerequisite secrets and install 2.0.0 as a NEW release
Move the data across
cpln port-forward. The procedure is the same as Restoring a Backup, with mongodump against the old proxy in place of downloading an archive.Point your applications at the new release, then uninstall the old one
Coming From 1.0.0
Template version 1.0.0 took the database credentials as plain Helm values and shipped a working default password, and it shipped a working replica set keyfile as a default too. Both were published in the public template repository, which means every 1.0.0 install that kept the defaults shares one publicly known password and one publicly known keyfile. The keyfile is what replica set members authenticate to each other with, so anyone holding it can join a member to your cluster.reveal on the database credentials must not also hand it the key that lets a member join your replica set.
While the old 1.0.0 cluster is still running and you need its credentials to dump from it, read them back out of the secrets that version created:
username, password and database. Failing that, they are in the values file you installed 1.0.0 with.
Prerequisites
Two secrets must exist before you install. Neither value passes through Helm values, so neither lands in the release. Secrets are org-level, so no GVC flag is involved.Create the database credentials secret
username, password and database. MongoDB is bootstrapped with this user, and this is the credential your applications put in their connection strings:mongodb.credentialsSecretName to the name you used.Create the replica set keyfile secret
plain holding the key that replica set members authenticate to each other with. Generate it — do not invent a passphrase:mongodb.keyfileSecretName to the name you used.Read either secret back later
A GVC Containing Every Location You List
A GVC must already exist, and it must contain every location you list inlocations. The requirement is one-directional — the GVC may have more locations than you list, and nothing MongoDB-related runs in those. Check what a GVC has before installing:
spec.staticPlacement.locationLinks. To add a missing one:
This workload location is deactivated because maxScale is set to 0. That is the mechanism that keeps a shared GVC safe — it is what a healthy install looks like, not a fault.Other Prerequisites
- For backups: an AWS or GCP cloud account and a storage bucket — see AWS S3 or GCS.
Installation
To install, follow the instructions for your preferred method:UI
CLI
Terraform
Pulumi
Configuration
The defaultvalues.yaml for this template:
Locations and Sizing
Each entry inlocations pairs a location with the number of mongod members to run there. Every location listed must already exist in the GVC you install into; extra GVC locations are ignored. Listing the same location twice, or giving one replicas: 0, is refused at render — to stop running somewhere, remove the entry.
Multi-Zone
SetmultiZone: true to spread replicas across availability zones within each location, protecting against zone-level failures. Verify your selected location(s) support multi-zone before enabling.
MongoDB Settings
mongodb.credentialsSecretName— Name of the dictionary secret holdingusername,passwordanddatabase. The cluster is bootstrapped with this user on first start, and this is the credential your applications use. Must exist before install — see Prerequisites.mongodb.keyfileSecretName— Name of the opaque secret holding the replica set keyfile. Must exist before install, and its contents must be generated withopenssl rand -base64 756.resources.cpu/resources.memory— Resource limits applied to each MongoDB replica.image— MongoDB image. Defaults topercona/percona-server-mongodb:8.0.
reveal on the database credentials cannot also read the key that lets a member join the replica set.
database entry of the credentials secret is for your own connection strings — the cluster is bootstrapped with the admin user, and MongoDB creates a database the first time you write to it.HAProxy Proxy
HAProxy is enabled by default and strongly recommended. In a MongoDB replica set, only the primary accepts writes — HAProxy provides a stable endpoint that routes all write traffic to the current primary automatically, surviving failover without any client-side changes.proxy.enabled— Enable or disable the proxy workload.proxy.minReplicas/proxy.maxReplicas— Number of HAProxy instances per configured location. Defaults to 2 for availability.proxy.resources— CPU and memory limits for the proxy workload.proxy.image— The HAProxy image. Defaults tohaproxy:2.9.
replica-0 in backup.location directly, so disabling the proxy does not affect it. The proxy matters for clients that cannot track the primary themselves.replicas. In 1.x every location got the largest location’s count, so an asymmetric roster such as 3 + 1 produced backends for members that never existed.Storage
volumeset.capacity— Initial volume size in GiB. Minimum is 10.volumeset.autoscaling.enabled— Set totrueto automatically expand volumes as data grows.volumeset.autoscaling.maxCapacity— Maximum volume size in GiB.volumeset.autoscaling.minFreePercentage— Percentage of free space that triggers a scale-up.volumeset.autoscaling.scalingFactor— Multiplier applied to the current capacity when scaling up.
Firewall
firewall.internalAllowType— Controls which workloads can reach MongoDB:same-gvc— All workloads in the same GVC (default).same-org— All workloads in the org.workload-list— Only the workloads listed infirewall.workloads, plus this release’s own workloads, which the template adds for you.
firewall.workloads— List of your own client workload paths, used only withworkload-list.
firewall.internalAllowType, keep re-testing rather than concluding the knob is broken.Connecting to MongoDB
Connect using the appropriate endpoint depending on your setup:readPreference=secondaryPreferred to your connection string and connect directly to a replica:
readPreference=primary (the default) when read-your-own-writes consistency is required.maxPoolSize in your MongoDB driver to prevent connection exhaustion. A per-app-replica pool of 10–50 connections is a reasonable starting point for most workloads.
The cluster has no public endpoint — it is reachable only from inside the org, subject to Firewall.
Failover Behavior
When the primary goes away, the remaining members elect a new one and the proxy re-routes to it. Clients connected through the proxy keep the same connection string and need no change. Measured on a three-member cluster with the primary killed abruptly — a forcedshutdown with no step-down, so MongoDB’s own election-timeout path ran rather than a coordinated handover — write availability was restored in 7 seconds or less through the unchanged proxy connection string. Data written before the failover survived, writes after it landed on the new primary, and the killed member rejoined by itself as a secondary about 44 seconds later, restarting in place on its own volume.
Backing Up
Whenbackup.enabled is true, a cron workload runs mongodump on the configured schedule and uploads a compressed BSON archive to AWS S3 or GCS. Set backup.provider and fill in the matching provider block.
backup.location names the one location the job runs in, and it must be one of your locations — the template refuses to render otherwise. That check matters: the platform accepts a placement naming a location that is not there, stores it, and the job then never runs anywhere, with nothing to observe.
The job connects to replica-0 in that location directly, not through the proxy, so proxy.enabled: false does not affect it.
Keep backup.schedule quoted in your values file. Any valid cron expression works, including one beginning with *.
AWS S3
Complete the following in your AWS account before installing:Create a bucket
backup.aws.bucket and backup.aws.region to match.Set up a Cloud Account
backup.aws.cloudAccountName to its name.Create an IAM policy
YOUR_BUCKET_NAME) and set backup.aws.policyName to its name:GCS
Complete the following in your GCP account before installing:Create a bucket
backup.gcp.bucket to its name.Set up a Cloud Account
backup.gcp.cloudAccountName to its name.Restoring a Backup
The cluster has no public endpoint, so the restore runs through acpln port-forward tunnel. You need the MongoDB Database Tools and your cloud CLI on the machine you run it from.
Find and download the archive
aws s3 ls s3://BUCKET_NAME/PREFIX/ (or gcloud storage ls gs://BUCKET_NAME/PREFIX/), then download the one you want:Open a tunnel to the proxy
RELEASE_NAME-mongo instead if you disabled the proxy. Leave this running.Restore through the tunnel
mongorestore from “a client with network access to the cluster” against a *.cpln.local address — an internal DNS name no external machine can resolve. The tunnel above is the working procedure, and it has been run verbatim end to end: archive downloaded, data destroyed, restored, and confirmed replicated to the secondaries.backup.mode: physical itself — see Backing Up for why. There is no PBM restore procedure to follow, because there never was a working one.Scaling
Scaling Up
Increasereplicas for a location in locations, or append a location that the GVC already has, and apply the template upgrade. New members connect to the primary through the seed list and self-register into the replica set automatically.
Keep the total inside MongoDB’s 7-voting-member limit, and remember that a single location holds at most 6 on a default quota — see Locations and Sizing.
Scaling Down
Before reducing a location’sreplicas, connect to the primary and remove each departing member:
Important Notes
- Both prerequisite secrets must exist before you install. A missing one wedges the deployment with no log output at all; the only diagnostic is
status.versions[].messagefromcpln workload get-deployments. See Prerequisites. - Generate the keyfile, never invent one. It must be 6-1024 characters from the base64 alphabet (
A-Z a-z 0-9 + / =) — achange-me-...style placeholder will not boot. Useopenssl rand -base64 756. - The keyfile cannot be changed after the cluster is initialized. Replacing it requires restarting every member with the new key at the same time.
- Never upgrade a 1.x release onto 2.0.0 in place — it deletes the GVC the 1.x chart created and everything in it. Migrate to a new release: Migrating from 1.x.
- The GVC must contain every location you list, and may contain more. A missing location is not caught at install: the members there never start, leaving a smaller replica set than you sized. Each member checks the GVC at boot — fatal on an empty data directory, a warning on one that already holds data.
- At most 7 members in total, and at most 6 in one location. MongoDB allows 7 voting members and the template refuses more; a single location is capped at 6 by a default org quota, so a 7-member set has to be split across locations.
- Never reorder
locationsafter install, only append. The first entry is the bootstrap location that initializes the replica set. - Sizing: 3 members is the usual minimum. A 2-member set is refused, because a majority of 2 is 2 and losing either leaves no primary — strictly worse than a single member.
- Rotating either secret does not restart anything. A
cpln://reference resolves when a replica starts and is never re-resolved while it lives, so the old value keeps working with no error until you runcpln workload force-redeployment. - An upgrade that changes the MongoDB tier rolls it — about 4 minutes for three members. Avoid other maintenance during that window.
backup.mode: physicalwas removed in 2.0.0 and now fails at render. Uselogical, whose restore is verified end to end.- Read from secondaries: To offload reads from the primary, use
readPreference=secondaryPreferredin your connection string. Secondary reads may be slightly stale due to replication lag. - Connection pooling: Configure
maxPoolSizein your MongoDB driver to prevent connection exhaustion. A per-app-replica pool of 10-50 is a reasonable starting point. - Data lives on the volume set and survives redeployment, but uninstalling deletes it.