> ## Documentation Index
> Fetch the complete documentation index at: https://playbook.smedleygroup.com/llms.txt
> Use this file to discover all available pages before exploring further.

# MongoDB Instance and Data Volume

> The Dockerised MongoDB server, the persistent data volume, TLS, and how the instance is provisioned.

This page describes the dedicated database: a MongoDB server running in Docker on an EC2 instance, its persistent data volume, and how it is built and secured.

## Overview

SG-Infra provisions one EC2 instance that runs MongoDB inside a Docker container, plus a separate persistent data volume that holds the database files. This is the dedicated database for Fleet Management Platform only at the time being. It is self-managed, like the legacy instance, but it is larger, runs a newer MongoDB, and separates the data from the instance so the instance can be rebuilt without losing data.

## The Instance

| Property | Value |
| - | - |
| Type | EC2 `t3.large` (larger than the legacy `t2.medium`) |
| Operating system | Latest Amazon Linux 2023 (not pinned, unlike the legacy repo) |
| Root volume | 30 GiB GP3, encrypted |
| Placement | A private-with-egress subnet, pinned to the data volume's Availability Zone |
| Name tag | `SG MongoDB Node Instance v3` |

## The Persistent Data Volume

A dedicated EBS volume holds the MongoDB data, defined in its own stack so its lifecycle is independent of the instance:

* **Size:** 256 GiB, GP3, encrypted, with provisioned throughput and IOPS.
* **Removal policy:** retain, so the volume and its data are not deleted if the stack or instance is removed.
* It is attached to the instance at `/dev/sdf` and mounted at `/data/mongodb`.
* On boot the instance checks whether the volume already has a filesystem. If it does, it mounts the existing data. If it does not, it formats the volume and mounts it. This is what allows the instance to be replaced while the data persists on the volume.

> [!NOTE]
>
> This separation of data from compute is the single biggest improvement over the legacy instance, where the data lived on the instance itself.

## How MongoDB Runs (Docker)

MongoDB runs as a Docker container (image `mongo:8.2`) managed by `docker-compose`, rather than being installed directly on the host. The container mounts the persistent volume for its data, along with the TLS material and the MongoDB configuration. It is set to restart unless stopped, and has a health check that pings the database and checks replica set status.

## How It Is Provisioned

The stack bundles the `setup` directory as an S3 asset, and the instance pulls and runs it on first boot through EC2 user data:

**1. Prepare the data volume**

Download the setup files from S3 and prepare the data volume (mount existing data, or format then mount).

**2. Generate TLS material**

A self-signed certificate authority and a server certificate are created on the instance, along with a replica set key file. The private keys are generated on the instance and are not stored in source control.

**3. Start MongoDB**

Install Docker and `docker-compose`, read or generate the admin password, start the container, and initiate a single node replica set named `rs0`.

**4. Store the connection details**

The connection string, the CA certificate and the admin password are written to the Secrets Manager secret so consumers can connect.

**5. Install tools and schedule backups**

Install the MongoDB tools and set up the backup cron jobs. See [Backups and Disaster Recovery](/software/developer/estate/infra/sg-infra/backups).

## Security Model

* **Network:** the MongoDB security group allows inbound only on `27017`, and only from the Lambda security group. The instance is in a private subnet with no public address.
* **Transport:** all connections require TLS. Unlike the legacy instance, the certificate authority is generated on the instance (not committed to the repo), certificate validation is enabled, and old TLS versions (1.0 and 1.1) are disabled.
* **Authentication:** enabled, with an admin user. The admin password is a 128 character random string, stored in Secrets Manager and reused across redeploys (the boot script reads the existing password from the secret if present).
* **Credentials for consumers:** the secret holds a ready to use connection string and the CA certificate, so a consuming system has everything it needs to connect.

> [!WARNING]
>
> There is one instance and a single node replica set, so the database server is still a single point of failure with no automatic failover. The improvement over the legacy instance is recovery, not high availability: because the data is on a retained, separate volume, the instance can be replaced and the data remains.

## Key Files

| File | Role |
| - | - |
| `CdkBuild/lib/sg_infra_mongo_instance_stack.ts` | The EC2 instance, role, volume attachment and boot user data |
| `CdkBuild/lib/sg_infra_volume_stack.ts` | The persistent data volume |
| `CdkBuild/lib/setup/docker-compose.yml` | The MongoDB container definition |
| `CdkBuild/lib/setup/mongod.conf` | The MongoDB server configuration (TLS, auth, replica set) |
| `CdkBuild/lib/setup/generate-keys.sh`, `start-mongo.sh` | The TLS generation and startup scripts |
| `CdkBuild/scripts/connect-ec2.bat` | The administrator connection helper |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.