diff --git a/.terraform.lock.hcl b/.terraform.lock.hcl
index 25d2e8b..4dccb26 100644
--- a/.terraform.lock.hcl
+++ b/.terraform.lock.hcl
@@ -170,3 +170,26 @@ provider "registry.terraform.io/telmate/proxmox" {
     "zh:fba1aff541133e2129dfda0160369635ab48503d5c44b8407ce5922ecc15d0bd",
   ]
 }
+
+provider "registry.terraform.io/thenicholi/json-formatter" {
+  version     = "0.1.1"
+  constraints = "~> 0.1"
+  hashes = [
+    "h1:U+zZH0uQVAsmWVeNNHSKW86BIhz9YpOCkfZsNQLTvfg=",
+    "zh:0edcb8104a87e1e007cfb18950009cdd98c9f8ee047851486a94aa4865532382",
+    "zh:14cd562ed9679131c2a64a3ade229ee8b2c4366ad9f0d8570c9868440e5a36c4",
+    "zh:204a4e3c9c4c3c8f988836640b1a4c47e43fcd821214671520dcab3d5bb76fb0",
+    "zh:3c6982ce4eed01306670558f55d616cb3ba65d2399575296d965a7c7ecf23280",
+    "zh:55e976507b22050f2204e077370f679972ad6b44b97970c3b48d4fb87e825081",
+    "zh:5a0c537048ab0d931daa7e7d55fe4c15bd48c0a7f2d05fdd6978841c614d4fb4",
+    "zh:5f96845dff445832b85d1cce349cb5fba9504fa178095c13943d6a16c79b1c29",
+    "zh:6be8dd856608bf5a45ede8126d76cd7c1f34b6db2b54971f9bdbc5ad2e1acd8d",
+    "zh:7e4d7138a472bd2b4eeac3fe09d0e4e886429c19a38be4d4db88f79982f09689",
+    "zh:9b12af85486a96aedd8d7984b0ff811a4b42e3d88dad1a3fb4c0b580d04fa425",
+    "zh:ac91277752e836fd560c3025684ebecb8bee43741f1f5afc185ece41934dd628",
+    "zh:af9852354805e7e2de0edb981d3750a942e4692201f11e937e281d8e086069a2",
+    "zh:b9db6195f81b1b215d2d1df1ab390a79d0a673fba3edf2365d3843fc641f66e4",
+    "zh:cb43ff8daa3556a049ab9add43a8c4ab079c5ac761afc599c1ffa480127d24d4",
+    "zh:db9babef5ab83b94c8d6ee06430373575d801c24408e18d52140d74d9b95f585",
+  ]
+}
diff --git a/lib/grey.ooo b/lib/grey.ooo
index e63eedc..4ff88bb 160000
--- a/lib/grey.ooo
+++ b/lib/grey.ooo
@@ -1 +1 @@
-Subproject commit e63eedc3702c83c85f6208cce2a50b17bea2cf38
+Subproject commit 4ff88bb5c9bed4c6ca7226f50886d117a6280f5f
diff --git a/provider.docker.tf b/provider.docker.tf
index 5cc1a5c..2bed425 100644
--- a/provider.docker.tf
+++ b/provider.docker.tf
@@ -1,28 +1,38 @@
+variable "docker_registry_auths" {
+  type = list(object({
+    address  = string
+    username = string
+    password = string
+  }))
+}
 provider "docker" {
   host = "tcp://${data.ssh_tunnel.management.local.address}"
-  registry_auth {
-    address  = "docker.io"
-    username = "matthewbaggett"
-    password = "dckr_pat_6ytcZqdfqRXzFYe5GUh79RfH1Hw"
+  dynamic "registry_auth" {
+    for_each = var.docker_registry_auths
+    content {
+      address  = registry_auth.value.address
+      username = registry_auth.value.username
+      password = registry_auth.value.password
+    }
   }
 }
 
-/*provider "docker" {
-  alias = "printi"
-  host  = "ssh://prin.ti"
-  registry_auth {
-    address  = "docker.io"
-    username = "matthewbaggett"
-    password = "dckr_pat_6ytcZqdfqRXzFYe5GUh79RfH1Hw"
-  }
-}*/
-
 provider "docker" {
   alias = "unifi"
   host  = "ssh://unifi.ti"
-  registry_auth {
-    address  = "docker.io"
-    username = "matthewbaggett"
-    password = "dckr_pat_6ytcZqdfqRXzFYe5GUh79RfH1Hw"
+  dynamic "registry_auth" {
+    for_each = var.docker_registry_auths
+    content {
+      address  = registry_auth.value.address
+      username = registry_auth.value.username
+      password = registry_auth.value.password
+    }
   }
 }
+
+locals {
+  placement_constraints = {
+    default = []
+    unifi   = ["node.hostname == unifi.ti"]
+  }
+}
\ No newline at end of file
diff --git a/ubiquity.tf b/ubiquity.tf
new file mode 100644
index 0000000..bb60f1a
--- /dev/null
+++ b/ubiquity.tf
@@ -0,0 +1,69 @@
+data "docker_registry_image" "unifi_controller" {
+  name = "jacobalberty/unifi:v9"
+}
+resource "docker_service" "unifi_controller" {
+  name     = "unifi_controller"
+  provider = docker.unifi
+  task_spec {
+    container_spec {
+      image = "${data.docker_registry_image.unifi_controller.name}@${data.docker_registry_image.unifi_controller.sha256_digest}"
+      env = {
+        TZ = "Europe/Amsterdam"
+      }
+      mounts {
+        target = "/unifi"
+        source = "/home/techinc/unifi"
+        type   = "bind"
+      }
+    }
+    restart_policy {
+      condition = "any"
+      delay     = "0s"
+      window    = "0s"
+    }
+  }
+  endpoint_spec {
+    ports {
+      target_port    = 8443
+      published_port = 443
+      publish_mode   = "ingress"
+    }
+    ports {
+      target_port    = 8443
+      published_port = 8443
+      publish_mode   = "ingress"
+    }
+    ports {
+      target_port    = 3478
+      published_port = 3478
+      publish_mode   = "ingress"
+      protocol       = "udp"
+    }
+    ports {
+      target_port    = 10001
+      published_port = 10001
+      publish_mode   = "ingress"
+      protocol       = "udp"
+    }
+    ports {
+      target_port    = 8080
+      published_port = 8080
+      publish_mode   = "ingress"
+    }
+  }
+}
+
+module "http2https" {
+  providers  = { docker = docker.unifi }
+  source     = "./lib/grey.ooo/products/iperf"
+  stack_name = "network"
+  ports      = [{ container = 80, host = 80, protocol = "tcp" }]
+  //placement_constraints = local.placement_constraints.unifi
+}
+module "iperf" {
+  providers  = { docker = docker.unifi }
+  source     = "./lib/grey.ooo/products/http2https"
+  stack_name = "network"
+  ports      = [{ container = 5201, host = 5201, protocol = "tcp" }, { container = 5201, host = 5201, protocol = "udp" }]
+  //placement_constraints = local.placement_constraints.unifi
+}
diff --git a/ubiquity.tf_ b/ubiquity.tf_
deleted file mode 100644
index 8eb5e17..0000000
--- a/ubiquity.tf_
+++ /dev/null
@@ -1,143 +0,0 @@
-data "docker_registry_image" "unifi_controller" {
-  name = "jacobalberty/unifi"
-}
-resource "docker_service" "unifi_controller" {
-  name     = "unifi_controller"
-  provider = docker.unifi
-  task_spec {
-    container_spec {
-      image = "${data.docker_registry_image.unifi_controller.name}@${data.docker_registry_image.unifi_controller.sha256_digest}"
-      env = {
-        TZ = "Europe/Amsterdam"
-      }
-      mounts {
-        target = "/unifi"
-        source = "/home/techinc/unifi"
-        type   = "bind"
-      }
-    }
-    restart_policy {
-      condition = "any"
-      delay     = "0s"
-      window    = "0s"
-    }
-  }
-  endpoint_spec {
-    ports {
-      target_port    = 8443
-      published_port = 443
-      publish_mode   = "ingress"
-    }
-    ports {
-      target_port    = 8443
-      published_port = 8443
-      publish_mode   = "ingress"
-    }
-    ports {
-      target_port    = 3478
-      published_port = 3478
-      publish_mode   = "ingress"
-      protocol       = "udp"
-    }
-    ports {
-      target_port    = 10001
-      published_port = 10001
-      publish_mode   = "ingress"
-      protocol       = "udp"
-    }
-    ports {
-      target_port    = 8080
-      published_port = 8080
-      publish_mode   = "ingress"
-    }
-  }
-}
-
-resource "docker_service" "unifi_controller_restored_from_backup" {
-  name     = "unifi_controller_restored_from_backup"
-  provider = docker.unifi
-  task_spec {
-    container_spec {
-      image = "${data.docker_registry_image.unifi_controller.name}@${data.docker_registry_image.unifi_controller.sha256_digest}"
-      env = {
-        TZ = "Europe/Amsterdam"
-      }
-      mounts {
-        target = "/unifi"
-        source = "/home/techinc/unifi_restored_from_backup"
-        type   = "bind"
-      }
-    }
-    restart_policy {
-      condition = "any"
-      delay     = "0s"
-      window    = "0s"
-    }
-  }
-  endpoint_spec {
-    ports {
-      target_port    = 443
-      published_port = 444
-      publish_mode   = "ingress"
-    }
-  }
-}
-
-data "docker_registry_image" "http2https" {
-  name = "articulate/http-to-https"
-}
-resource "docker_service" "unifi_http2https" {
-  name     = "http2https"
-  provider = docker.unifi
-
-  task_spec {
-    container_spec {
-      image = "${data.docker_registry_image.http2https.name}@${data.docker_registry_image.http2https.sha256_digest}"
-    }
-    restart_policy {
-      condition = "any"
-      delay     = "0s"
-      window    = "0s"
-    }
-  }
-  endpoint_spec {
-    ports {
-      target_port    = 80
-      published_port = 80
-      publish_mode   = "ingress"
-    }
-  }
-}
-
-data "docker_registry_image" "iperf" {
-  name     = "loganmarchione/docker-iperf3:latest"
-  provider = docker.unifi
-}
-resource "docker_service" "unifi_iperf" {
-  name     = "iperf"
-  provider = docker.unifi
-  task_spec {
-    container_spec {
-      image = "${data.docker_registry_image.iperf.name}@${data.docker_registry_image.iperf.sha256_digest}"
-    }
-    restart_policy {
-      condition = "any"
-      delay     = "0s"
-      window    = "0s"
-    }
-  }
-  endpoint_spec {
-    ports {
-      target_port    = 5201
-      published_port = 5201
-      publish_mode   = "ingress"
-      protocol       = "tcp"
-    }
-    ports {
-      target_port    = 5201
-      published_port = 5201
-      publish_mode   = "ingress"
-      protocol       = "udp"
-    }
-  }
-}
\ No newline at end of file