diff --git a/modules/datastore/mysql/logical/1.0/facets.yaml b/modules/datastore/mysql/logical/1.0/facets.yaml new file mode 100644 index 00000000..8341857c --- /dev/null +++ b/modules/datastore/mysql/logical/1.0/facets.yaml @@ -0,0 +1,61 @@ +intent: mysql +flavor: logical +version: '1.0' +clouds: +- aws +- gcp +- azure +description: Logical — a logical database hosted on an existing/shared MySQL instance; + re-exposes its connection outputs (no resources created). Useful for staging database + consolidation where several logical databases share one physical instance. +intentDetails: + type: Datastores + description: A logical database on an existing/shared MySQL instance — re-exposes its connection outputs + displayName: MySQL + iconUrl: https://raw.githubusercontent.com/Facets-cloud/facets-modules-redesign/main/icons/mysql.svg +spec: + title: MySQL Logical Database + description: Logical — a logical database hosted on an existing/shared MySQL + instance; re-exposes its connection outputs (no resources created). Points at + another MySQL resource (the source) and optionally overrides the logical database + name in the connection string. + type: object + x-ui-order: + - source + - database_name + properties: + source: + type: object + title: Source MySQL Datastore + description: The existing MySQL datastore whose outputs should be re-exposed. + Resolves to the full outputs (attributes + interfaces) of the selected + resource. + x-ui-output-type: '@facets/mysql' + database_name: + type: string + title: Logical Database Name + description: Optional logical database to expose on the shared physical + instance. When set, the re-emitted connection_string targets this database + instead of the source's database. + pattern: ^[a-zA-Z][a-zA-Z0-9_]*$ + minLength: 1 + maxLength: 64 + required: + - source +outputs: + default: + type: '@facets/mysql' + title: MySQL Logical Database +iac: + validated_files: + - main.tf + - variables.tf + - outputs.tf +sample: + kind: mysql + flavor: logical + version: '1.0' + disabled: true + spec: + source: {} + database_name: reporting diff --git a/modules/datastore/mysql/logical/1.0/main.tf b/modules/datastore/mysql/logical/1.0/main.tf new file mode 100644 index 00000000..321877e8 --- /dev/null +++ b/modules/datastore/mysql/logical/1.0/main.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 1.0" +} + +# This is a reference / passthrough flavour. It provisions NO cloud resources and +# requires NO providers. It re-exposes the outputs of an existing MySQL datastore +# (var.instance.spec.source) so that consumers can wire to a logical database that +# shares a physical instance (e.g. staging database consolidation). +# +# All output wiring lives in outputs.tf. diff --git a/modules/datastore/mysql/logical/1.0/outputs.tf b/modules/datastore/mysql/logical/1.0/outputs.tf new file mode 100644 index 00000000..17292776 --- /dev/null +++ b/modules/datastore/mysql/logical/1.0/outputs.tf @@ -0,0 +1,58 @@ +locals { + source = var.instance.spec.source + source_ifc = lookup(local.source, "interfaces", {}) + + source_reader = lookup(local.source_ifc, "reader", {}) + source_writer = lookup(local.source_ifc, "writer", {}) + + # Optional logical database override. When set, the connection_string is rebuilt + # to target this database on the same physical host/port; otherwise the source's + # connection_string and database are re-emitted unchanged. + override_database = lookup(var.instance.spec, "database_name", null) + + reader_host = lookup(local.source_reader, "host", null) + reader_port = lookup(local.source_reader, "port", null) + writer_host = lookup(local.source_writer, "host", null) + writer_port = lookup(local.source_writer, "port", null) + + reader_database = local.override_database != null ? local.override_database : lookup(local.source_reader, "database", null) + writer_database = local.override_database != null ? local.override_database : lookup(local.source_writer, "database", null) + + reader_connection_string = local.override_database != null ? format( + "mysql://%s:%s/%s", + local.reader_host, + local.reader_port, + local.override_database + ) : lookup(local.source_reader, "connection_string", null) + + writer_connection_string = local.override_database != null ? format( + "mysql://%s:%s/%s", + local.writer_host, + local.writer_port, + local.override_database + ) : lookup(local.source_writer, "connection_string", null) + + # Re-emit the @facets/mysql contract from the source. + output_attributes = lookup(local.source, "attributes", {}) + + output_interfaces = { + reader = { + host = local.reader_host + port = local.reader_port + username = lookup(local.source_reader, "username", null) + password = lookup(local.source_reader, "password", null) + database = local.reader_database + connection_string = local.reader_connection_string + secrets = lookup(local.source_reader, "secrets", ["password", "connection_string"]) + } + writer = { + host = local.writer_host + port = local.writer_port + username = lookup(local.source_writer, "username", null) + password = lookup(local.source_writer, "password", null) + database = local.writer_database + connection_string = local.writer_connection_string + secrets = lookup(local.source_writer, "secrets", ["password", "connection_string"]) + } + } +} diff --git a/modules/datastore/mysql/logical/1.0/variables.tf b/modules/datastore/mysql/logical/1.0/variables.tf new file mode 100644 index 00000000..4c33ecc2 --- /dev/null +++ b/modules/datastore/mysql/logical/1.0/variables.tf @@ -0,0 +1,56 @@ +variable "instance" { + description = "Reference (passthrough) to an existing MySQL datastore — re-exposes another MySQL resource's outputs without provisioning any cloud resource." + type = object({ + kind = string + flavor = string + version = string + spec = object({ + # source resolves (via x-ui-output-type: @facets/mysql) to the FULL outputs + # of the selected MySQL resource: its attributes + interfaces (reader/writer). + source = object({ + attributes = optional(any, {}) + interfaces = optional(object({ + reader = optional(object({ + host = optional(string) + port = optional(number) + username = optional(string) + password = optional(string) + database = optional(string) + connection_string = optional(string) + secrets = optional(list(string), []) + }), {}) + writer = optional(object({ + host = optional(string) + port = optional(number) + username = optional(string) + password = optional(string) + database = optional(string) + connection_string = optional(string) + secrets = optional(list(string), []) + }), {}) + }), {}) + }) + database_name = optional(string) + }) + }) +} + +variable "instance_name" { + description = "The architectural name for the resource as added in the Facets blueprint designer." + type = string +} + +variable "environment" { + description = "An object containing details about the environment." + type = object({ + name = string + unique_name = string + cloud_tags = map(string) + }) +} + +variable "inputs" { + description = "A map of inputs requested by the module developer. This passthrough module requires none." + type = object({}) + default = {} +}