MongoDB Sink¶
varTrack writes config values to MongoDB. The datasource's update_strategy picks the shape: document (one nested document per file, the default), key-value (one document per key), or file (one document per file, in the shape the file parsed to).
Configuration¶
datasources: [{
mongo: {
tag: "" // optional — resolves to "mongo-{tag}"
endpoint: "mongodb://mongo:27017"
database: "vartrack"
collection: "variables"
update_strategy: "STRATEGY_DOCUMENT" // the default; or "STRATEGY_KEY_VALUE", "STRATEGY_FILE"
}
}]
connect_timeout_ms (default 0: the driver's own waits) is how long the sink looks for the server before a write or a read fails. Set it (5000 is a sensible value): with a stopped server the driver otherwise waits 20 s to connect and 30 s to find a server, more than once per operation, so the web UI keeps saying "in sync" for a minute before it says it cannot read the sink.
With authentication¶
datasources: [{
mongo: {
endpoint: "mongodb://mongo:27017"
database: "vartrack"
collection: "variables"
username: "vartrack"
password: "secret" // or a Vault reference
}
}]
With TLS¶
datasources: [{
mongo: {
endpoint: "mongodb://mongo:27017"
database: "vartrack"
collection: "variables"
ssl: true
ssl_ca_path: "/etc/ssl/mongo-ca.pem"
}
}]
Write strategies¶
The examples below sync this file:
In the demo
The demo's mongo, mongo-primary and mongo-dr datasources use STRATEGY_DOCUMENT (collections variables, primary_vars, dr_vars),
mongo-document uses it with its own collection, mongo-file uses STRATEGY_FILE, and mongo-kv (collection kv_vars) is the one that
uses STRATEGY_KEY_VALUE: the shape that keeps single keys, so it is where prune and per-key drift show.
STRATEGY_KEY_VALUE¶
Each config key is stored as a separate document, its value as a string. It is the strategy that keeps a key on its own, so it is the one a prune can delete from (a document strategy replaces the whole file's document on every sync):
{ "_vt_env": "production", "key": "database.host", "value": "mongo.prod.internal" }
{ "_vt_env": "production", "key": "max_connections", "value": "50" }
{ "_vt_env": "production", "key": "regions.0", "value": "eu" }
Reading a value: db.collection.findOne({ _vt_env: "production", key: "database.host" }).value
STRATEGY_DOCUMENT (default)¶
One document per environment and file, with the config always nested under data. Values keep the types and arrays they have in the file:
{
"_vt_env": "production",
"_vt_file": "configs/app.yaml",
"data": {
"database": { "host": "mongo.prod.internal" },
"max_connections": 50,
"regions": ["eu", "us"]
}
}
Reading a value: db.collection.findOne({ _vt_env: "production" }).data.database.host
A flat file (.env, .properties) is nested by the dots in its keys: db.host=x is stored as data: { db: { host: "x" } }. A file where one key is both a value and the parent of other keys (log=on next to log.level=info) has no nested form, so its sync fails and names the key. Use STRATEGY_FILE for such a file.
STRATEGY_FILE¶
One document per environment and file, with data in the shape the file parsed to: nested for YAML, JSON, TOML and the other tree formats (as in STRATEGY_DOCUMENT), flat for .env and .properties:
{
"_vt_env": "production",
"_vt_file": "configs/app.properties",
"data": {
"database.host": "mongo.prod.internal",
"max_connections": "50"
}
}
With either document strategy, every sync replaces the file's document, so keys removed from Git disappear without prune. Switching a datasource from STRATEGY_KEY_VALUE to one of them removes that file's per-key documents on the next sync; switching back to STRATEGY_KEY_VALUE removes the file's document the same way. The orchestrator logs a warning with the number of documents removed, and the UI shows a Shape changed event on the environment.
The default changed
A Mongo datasource that sets no update_strategy used to store one document per key. It now stores one nested document per file. To keep per-key documents, set update_strategy: "STRATEGY_KEY_VALUE"; without it, the next sync replaces the per-key documents of each file with its document, logs how many it removed and shows a Shape changed event.
One write, one step¶
STRATEGY_DOCUMENT and STRATEGY_FILE write a file as its document plus the removal of the documents of another shape it replaces (after an update_strategy change). On a replica set or a sharded cluster those two operations are one session transaction, so a failure leaves the file as it was. Transactions need MongoDB 4.4 or later (an env_as_collection collection is created inside the transaction).
A standalone server has no transactions: varTrack asks the server once, on the first write, and logs that it falls back. There the document is replaced in one replace_one, and a sync that fails after writing a file puts it back from the snapshot it took before (see A sync failed). STRATEGY_KEY_VALUE writes one document per key with one bulk_write and is not wrapped in a transaction: it is not atomic across keys.
Per-environment collections¶
Set env_as_collection: true to write each environment into its own collection instead of a fixed one:
datasources: [{
mongo: {
database: "vartrack"
collection: "configs"
env_as_collection: true // production → "configs_production", pr-42 → "configs_pr-42"
}
}]
Destination template¶
The destination_template field controls which collection data is written to:
rules: [{
platform: "github"
datasource: "mongo"
file_name: "app-settings.yaml"
destination_template: "{env}-config"
branch_map: {
main: "production"
develop: "staging"
}
}]
| Push branch | Collection written |
|---|---|
main |
production-config |
develop |
staging-config |
| PR #42 | pr-42-config |
Drift detection¶
The watcher asks the orchestrator each poll; the orchestrator reads the keys varTrack wrote — the key → value documents, or the keys inside data and compares them with what it last synced from Git — a changed or missing key is drift (Drift Detection).
Enable self-heal to restore automatically: