Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions modules/datastore/mongo/logical/1.0/facets.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
intent: mongo
flavor: logical
version: '1.0'
clouds:
- aws
- gcp
- azure
description: >
Logical — a logical database hosted on an existing / shared mongo /
DocumentDB instance; re-exposes its connection outputs (no resources created).
intentDetails:
type: Datastores
description: Logical database on an existing / shared MongoDB-compatible instance
displayName: MongoDB
iconUrl: https://raw.githubusercontent.com/Facets-cloud/facets-modules-redesign/main/icons/mongo.svg
spec:
title: MongoDB Logical Database
description: >
Logical — a logical database hosted on an existing / shared mongo /
DocumentDB instance; re-exposes its connection outputs (no resources
created). Useful for consolidating multiple logical databases onto a single
physical cluster (e.g. shared staging DB).
type: object
x-ui-order:
- source
- database_name
properties:
source:
type: object
title: Source MongoDB Datastore
description: >
Select an existing mongo / DocumentDB datastore. Its full outputs
(interfaces + attributes) are resolved into this field. Override per
environment to point at the right physical cluster.
x-ui-output-type: '@facets/mongo'
database_name:
type: string
title: Logical Database Name
description: >
Optional logical database to target in the connection string. When set,
the database name is injected into the re-exposed connection strings
while preserving tls / replicaSet parameters.
required:
- source
inputs: {}
outputs:
default:
type: '@facets/mongo'
title: MongoDB Reference
iac:
validated_files:
- main.tf
- variables.tf
- locals.tf
sample:
kind: mongo
flavor: logical
version: '1.0'
disabled: true
spec:
source: {}
database_name: app
36 changes: 36 additions & 0 deletions modules/datastore/mongo/logical/1.0/locals.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# locals.tf - Computations for the mongo reference (passthrough) flavour.
# No cloud resources are created by this flavour.

locals {
source_interfaces = lookup(var.instance.spec.source, "interfaces", {})

writer = lookup(local.source_interfaces, "writer", {})
reader = lookup(local.source_interfaces, "reader", {})
cluster = lookup(local.source_interfaces, "cluster", {})

database_name = lookup(var.instance.spec, "database_name", null)
has_database = local.database_name != null && local.database_name != ""

# A mongo connection string looks like:
# mongodb://user:pass@host:port/<db>?tls=true&replicaSet=rs0&...
# To target a logical database we splice <db> between the authority and the
# query string, preserving the "?..." params (tls / replicaSet / etc.).
rewrite_db = {
for k, cs in {
writer = lookup(local.writer, "connection_string", null)
reader = lookup(local.reader, "connection_string", null)
cluster = lookup(local.cluster, "connection_string", null)
} : k => (
cs == null ? null :
!local.has_database ? cs :
length(split("?", cs)) > 1 ?
format(
"%s/%s?%s",
replace(split("?", cs)[0], "/\\/[^/]*$/", ""),
local.database_name,
join("?", slice(split("?", cs), 1, length(split("?", cs))))
) :
format("%s/%s", replace(cs, "/\\/[^/]*$/", ""), local.database_name)
)
}
}
10 changes: 10 additions & 0 deletions modules/datastore/mongo/logical/1.0/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# main.tf - Reference flavour for mongo.
#
# This flavour creates NO cloud resources and requires NO provider. It is a pure
# passthrough that re-exposes the outputs of an already-provisioned mongo /
# DocumentDB datastore selected via spec.source. See locals.tf for the contract
# re-emission and outputs.tf for the exposed interfaces.

terraform {
required_version = ">= 1.0"
}
35 changes: 35 additions & 0 deletions modules/datastore/mongo/logical/1.0/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
locals {
output_attributes = lookup(var.instance.spec.source, "attributes", {})

# Pure passthrough of the referenced datastore's mongo contract. Absent fields
# surface as null; when database_name is set, connection strings and the
# logical name target that database (query params such as tls / replicaSet are
# preserved by local.rewrite_db).
output_interfaces = {
writer = {
host = lookup(local.writer, "host", null)
port = lookup(local.writer, "port", null)
username = lookup(local.writer, "username", null)
password = lookup(local.writer, "password", null)
connection_string = local.rewrite_db["writer"]
name = local.has_database ? local.database_name : lookup(local.writer, "name", null)
secrets = lookup(local.writer, "secrets", ["password", "connection_string"])
}
reader = {
host = lookup(local.reader, "host", null)
port = lookup(local.reader, "port", null)
username = lookup(local.reader, "username", null)
password = lookup(local.reader, "password", null)
connection_string = local.rewrite_db["reader"]
name = local.has_database ? local.database_name : lookup(local.reader, "name", null)
secrets = lookup(local.reader, "secrets", ["password", "connection_string"])
}
cluster = {
endpoint = lookup(local.cluster, "endpoint", null)
username = lookup(local.cluster, "username", null)
password = lookup(local.cluster, "password", null)
connection_string = local.rewrite_db["cluster"]
secrets = lookup(local.cluster, "secrets", ["password", "connection_string"])
}
}
}
66 changes: 66 additions & 0 deletions modules/datastore/mongo/logical/1.0/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
variable "instance" {
description = "Reference an existing MongoDB / DocumentDB datastore (passthrough, no resources)."
type = object({
kind = string
flavor = string
version = string
spec = object({
# Full outputs of the selected source mongo datastore, resolved by the
# platform from the spec field's x-ui-output-type ('@facets/mongo').
source = object({
attributes = optional(object({}), {})
interfaces = optional(object({
writer = optional(object({
host = optional(string)
port = optional(string)
username = optional(string)
password = optional(string)
connection_string = optional(string)
name = optional(string)
secrets = optional(list(string), [])
}), {})
reader = optional(object({
host = optional(string)
port = optional(string)
username = optional(string)
password = optional(string)
connection_string = optional(string)
name = optional(string)
secrets = optional(list(string), [])
}), {})
cluster = optional(object({
endpoint = optional(string)
username = optional(string)
password = optional(string)
connection_string = optional(string)
secrets = optional(list(string), [])
}), {})
}), {})
})
# Optional logical database to target in the re-exposed connection string.
database_name = optional(string)
})
})
}

variable "instance_name" {
description = "The architectural name of the resource as added in the blueprint."
type = string
default = ""
}

variable "environment" {
description = "Environment-level metadata injected by the platform."
type = object({
name = optional(string)
unique_name = optional(string)
namespace = optional(string)
})
default = {}
}

variable "inputs" {
description = "No dependency inputs — this flavour is a pure passthrough."
type = object({})
default = {}
}