From e63eedc3702c83c85f6208cce2a50b17bea2cf38 Mon Sep 17 00:00:00 2001
From: Matthew Baggett <matthew@baggett.me>
Date: Tue, 21 Jan 2025 21:38:56 +0100
Subject: [PATCH] Mqtt as a module.

---
 products/mqtt/inputs.tf      | 45 ++++++++++++++++++++++++++++++++++++
 products/mqtt/mosquitto.conf | 16 +++++++++++++
 products/mqtt/mqtt.tf        | 19 +++++++++++++++
 products/mqtt/network.tf     |  4 ++++
 products/mqtt/outputs.tf     |  9 ++++++++
 products/mqtt/terraform.tf   | 20 ++++++++++++++++
 6 files changed, 113 insertions(+)
 create mode 100644 products/mqtt/inputs.tf
 create mode 100644 products/mqtt/mosquitto.conf
 create mode 100644 products/mqtt/mqtt.tf
 create mode 100644 products/mqtt/network.tf
 create mode 100644 products/mqtt/outputs.tf
 create mode 100644 products/mqtt/terraform.tf

diff --git a/products/mqtt/inputs.tf b/products/mqtt/inputs.tf
new file mode 100644
index 0000000..7291fa8
--- /dev/null
+++ b/products/mqtt/inputs.tf
@@ -0,0 +1,45 @@
+variable "stack_name" {
+  default     = "mqtt"
+  type        = string
+  description = "The name of the stack to create."
+}
+variable "networks" {
+  type = list(object({
+    name = string
+    id   = string
+  }))
+  default     = []
+  description = "A list of network names to attach the service to."
+}
+variable "traefik" {
+  default = null
+  type = object({
+    domain           = string
+    port             = optional(number)
+    non-ssl          = optional(bool, true)
+    ssl              = optional(bool, false)
+    rule             = optional(string)
+    middlewares      = optional(list(string))
+    network          = optional(object({ name = string, id = string }))
+    basic-auth-users = optional(list(string))
+  })
+  description = "Whether to enable traefik for the service."
+}
+variable "placement_constraints" {
+  default     = []
+  type        = list(string)
+  description = "Docker Swarm placement constraints"
+}
+variable "mounts" {
+  type        = map(string)
+  default     = {}
+  description = "A map of host paths to container paths to mount. The key is the host path, and the value is the container path."
+}
+variable "ports" {
+  type = list(object({
+    host      = optional(number, null)
+    container = number
+    protocol  = optional(string, "tcp")
+  }))
+  default = []
+}
\ No newline at end of file
diff --git a/products/mqtt/mosquitto.conf b/products/mqtt/mosquitto.conf
new file mode 100644
index 0000000..8b7bd9f
--- /dev/null
+++ b/products/mqtt/mosquitto.conf
@@ -0,0 +1,16 @@
+listener 1883 0.0.0.0
+socket_domain ipv4
+
+pid_file /tmp/mosquitto.pid
+
+persistence true
+persistence_location /mosquitto/data/
+
+log_dest file /mosquitto/logs/mosquitto.log
+log_dest stdout
+
+#password_file /mosquitto/config/mosquitto.passwd
+allow_anonymous true
+
+listener 8080 127.0.0.1
+protocol websockets
\ No newline at end of file
diff --git a/products/mqtt/mqtt.tf b/products/mqtt/mqtt.tf
new file mode 100644
index 0000000..9a55f83
--- /dev/null
+++ b/products/mqtt/mqtt.tf
@@ -0,0 +1,19 @@
+module "service" {
+  source                = "../../docker/service"
+  image                 = "eclipse-mosquitto:latest"
+  service_name          = "mqtt"
+  stack_name            = var.stack_name
+  networks              = concat(var.networks, [module.network.network])
+  traefik               = var.traefik
+  placement_constraints = var.placement_constraints
+  mounts                = var.mounts
+  ports                 = var.ports
+  configs = {
+    "/mosquitto/config/mosquitto.conf" = templatefile("${path.module}/mosquitto.conf", {})
+  }
+  volumes = {
+    "mqtt_data" = "/mosquitto/data"
+    "mqtt_logs" = "/mosquitto/logs"
+  }
+  converge_enable = false
+}
diff --git a/products/mqtt/network.tf b/products/mqtt/network.tf
new file mode 100644
index 0000000..2306555
--- /dev/null
+++ b/products/mqtt/network.tf
@@ -0,0 +1,4 @@
+module "network" {
+  source     = "../../docker/network"
+  stack_name = var.stack_name
+}
\ No newline at end of file
diff --git a/products/mqtt/outputs.tf b/products/mqtt/outputs.tf
new file mode 100644
index 0000000..90b3227
--- /dev/null
+++ b/products/mqtt/outputs.tf
@@ -0,0 +1,9 @@
+output "docker_service" {
+  value = module.service.docker_service
+}
+output "network" {
+  value = module.network.network
+}
+output "endpoint" {
+  value = replace(module.service.endpoint, "http://", "mqtt://")
+}
\ No newline at end of file
diff --git a/products/mqtt/terraform.tf b/products/mqtt/terraform.tf
new file mode 100644
index 0000000..bacc852
--- /dev/null
+++ b/products/mqtt/terraform.tf
@@ -0,0 +1,20 @@
+terraform {
+  required_version = "~> 1.6"
+
+  required_providers {
+    docker = {
+      source  = "kreuzwerker/docker"
+      version = "~> 3.0"
+    }
+    random = {
+      source  = "hashicorp/random"
+      version = "~> 3.5"
+    }
+    htpasswd = {
+      source  = "loafoe/htpasswd"
+      version = "~> 1.0"
+    }
+  }
+}
+
+