Files
ouranos/terraform/containers.tf
Robert Helewka 9bfa9a3617 feat(terraform): expand caliban port forwards and document port ranges
- Add proxy devices on caliban for SSH (25512), Postgres (25515),
  and three web ports (25516-25518) alongside existing RDP forward
- Remove HTTP/HTTPS proxy devices from prospero (now handled via
  HAProxy on titania)
- Document Incus port forwarding ranges (25510-25599) per host in
  ouranos.md and fix a typo
2026-06-07 06:40:42 -04:00

328 lines
8.5 KiB
HCL

locals {
# Common cloud-init configuration
base_cloud_init = <<EOT
#cloud-config
package_update: true
packages:
- apt-utils
- openssh-server
users:
- name: ${var.keeper_user}
uid: ${var.keeper_uid}
homedir: /srv/${var.keeper_user}
sudo: ALL=(ALL) NOPASSWD:ALL
shell: /bin/bash
groups: sudo
lock_passwd: true
EOT
# Uranian host definitions - Red Panda Approved
uranian_hosts = {
oberon = {
description = "Docker Host + MCP Switchboard - King of Fairies orchestrating containers and managing MCP infrastructure"
remote = "local"
role = "container_orchestration"
image = "noble"
config = {
"security.nesting" = true
"raw.lxc" = "lxc.apparmor.profile=unconfined"
}
devices = [{
name = "app_ports"
type = "proxy"
properties = {
listen = "tcp:0.0.0.0:25590-25599"
connect = "tcp:127.0.0.1:25590-25599"
}
}]
}
portia = {
description = "PostgreSQL Host - Intelligent database justice"
role = "database"
image = "noble"
config = {}
devices = []
}
ariel = {
description = "Neo4j Host - Ethereal graph connections"
role = "graph_database"
image = "noble"
config = {
"security.nesting" = true
"raw.lxc" = "lxc.apparmor.profile=unconfined"
}
devices = [{
name = "neo4j_ports"
type = "proxy"
properties = {
listen = "tcp:0.0.0.0:25554"
connect = "tcp:127.0.0.1:25554"
}
}]
}
umbriel = {
description = "Neo4j Host (Mnemosyne) - Dusky sprite keeping the memory graph"
role = "graph_database"
image = "noble"
config = {
"security.nesting" = true
"raw.lxc" = "lxc.apparmor.profile=unconfined"
}
devices = [{
name = "neo4j_ports"
type = "proxy"
properties = {
listen = "tcp:0.0.0.0:25555"
connect = "tcp:127.0.0.1:25555"
}
}]
}
miranda = {
description = "Dedicated Docker Host for MCP Servers - Curious bridge between worlds"
role = "mcp_docker_host"
image = "noble"
config = {
"security.nesting" = true
"raw.lxc" = "lxc.apparmor.profile=unconfined"
}
devices = [{
name = "mcp_containers"
type = "proxy"
properties = {
listen = "tcp:0.0.0.0:25530-25539"
connect = "tcp:127.0.0.1:25530-25539"
}
},
{
name = "mcpo_ports"
type = "proxy"
properties = {
listen = "tcp:0.0.0.0:25560-25569"
connect = "tcp:127.0.0.1:25560-25569"
}
}]
}
sycorax = {
description = "Arke LLM Proxy - Original magical language power"
role = "language_models"
image = "noble"
config = {
"security.nesting" = true
"raw.lxc" = "lxc.apparmor.profile=unconfined"
}
devices = [{
name = "arke_ports"
type = "proxy"
properties = {
listen = "tcp:0.0.0.0:25540-25544"
connect = "tcp:127.0.0.1:25540-25544"
}
}]
}
puck = {
description = "Python App Host - Shape-shifting trickster"
role = "application_runtime"
image = "questing"
config = {
"security.nesting" = true
"raw.lxc" = "lxc.apparmor.profile=unconfined"
}
devices = [{
name = "puck_ports"
type = "proxy"
properties = {
listen = "tcp:0.0.0.0:25570-25588"
connect = "tcp:127.0.0.1:25570-25588"
}
},
{
name = "puck_rdp"
type = "proxy"
properties = {
listen = "tcp:0.0.0.0:25589"
connect = "tcp:127.0.0.1:3389"
}
},
{
name = "gpu"
type = "gpu"
properties = {}
}
]
}
caliban = {
description = "Agent S MCP Server - Autonomous computer agent learning through environmental interaction"
role = "agent_automation"
image = "questing"
config = {
"security.nesting" = true
"raw.lxc" = "lxc.apparmor.profile=unconfined"
}
devices = [
{
name = "caliban_rdp"
type = "proxy"
properties = {
listen = "tcp:0.0.0.0:25519"
connect = "tcp:127.0.0.1:3389"
}
},
{
name = "caliban_web3"
type = "proxy"
properties = {
listen = "tcp:0.0.0.0:25518"
connect = "tcp:127.0.0.1:8008"
}
},
{
name = "caliban_web2"
type = "proxy"
properties = {
listen = "tcp:0.0.0.0:25517"
connect = "tcp:127.0.0.1:8007"
}
},
{
name = "caliban_web1"
type = "proxy"
properties = {
listen = "tcp:0.0.0.0:25516"
connect = "tcp:127.0.0.1:8006"
}
},
{
name = "caliban_postgres"
type = "proxy"
properties = {
listen = "tcp:0.0.0.0:25515"
connect = "tcp:127.0.0.1:5432"
}
},
{
name = "caliban_ssh"
type = "proxy"
properties = {
listen = "tcp:0.0.0.0:25512"
connect = "tcp:127.0.0.1:22"
}
},
{
name = "gpu"
type = "gpu"
properties = {}
}
]
}
prospero = {
description = "Master magician observing events - PPLG observability stack with internal HAProxy"
role = "observability"
image = "noble"
config = {}
devices = []
}
titania = {
description = "Proxy & SSO Services - Queen of the fairies managing access and authentication"
role = "proxy_sso"
image = "noble"
config = {
"security.nesting" = true
"raw.lxc" = "lxc.apparmor.profile=unconfined"
}
devices = [
{
name = "https_standard"
type = "proxy"
properties = {
listen = "tcp:0.0.0.0:443"
connect = "tcp:127.0.0.1:8443"
}
},
{
name = "http_redirect"
type = "proxy"
properties = {
listen = "tcp:0.0.0.0:80"
connect = "tcp:127.0.0.1:8080"
}
},
{
name = "gitea_ssh"
type = "proxy"
properties = {
listen = "tcp:0.0.0.0:22022"
connect = "tcp:127.0.0.1:22022"
}
}
]
}
rosalind = {
description = "Nextcloud Host - Witty and resourceful moon for cloud collaboration (PHP, Go, Node.js runtimes)"
role = "collaboration"
image = "noble"
config = {
"security.nesting" = true
"raw.lxc" = "lxc.apparmor.profile=unconfined"
}
devices = [{
name = "nextcloud_data"
type = "disk"
properties = {
source = "nextcloud-data"
pool = "default"
path = "/mnt/nextcloud"
}
}]
}
}
images = {
noble = incus_image.noble.fingerprint
plucky = incus_image.plucky.fingerprint
questing = incus_image.questing.fingerprint
}
}
resource "incus_instance" "uranian_hosts" {
for_each = local.uranian_hosts
name = each.key
project = var.project_name
profiles = [var.profile_name]
image = local.images[each.value.image]
ephemeral = false
dynamic "device" {
for_each = lookup(each.value, "devices", [])
content {
name = device.value.name
type = device.value.type
properties = device.value.properties
}
}
config = merge(
{
"user.access_Interface" = "eth0"
"cloud-init.user-data" = local.base_cloud_init
"user.Environment" = "sandbox"
"user.ManagedBy" = "terraform"
"user.Role" = each.value.role
},
each.value.config
)
file {
target_path = "/srv/${var.keeper_user}/.ssh/authorized_keys"
source_path = var.ssh_key_path
uid = var.keeper_uid
gid = var.keeper_uid
mode = 0750
create_directories = true
}
lifecycle {
ignore_changes = [config]
}
}