prepare neuron-tim namespace for Tim's future Neuron instance

Adds the neuron-tim namespace (via Terraform) and a full Argo CD
app + k8s manifests mirroring neuron-prod. All deployments set to
replicas=0 — nothing runs until Tim's imprint is ready and Vault
secrets are populated at secret/neuron-technologies/tim.
This commit is contained in:
Will Anderson
2026-04-24 12:52:36 -05:00
parent 92743b1efc
commit 336a9333a2
10 changed files with 316 additions and 0 deletions
+20
View File
@@ -0,0 +1,20 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: neuron-tim
namespace: argocd
spec:
project: default
source:
repoURL: http://10.43.1.53:3000/will/infrastructure.git
targetRevision: main
path: servers/legion/k8s/neuron-technologies/tim
destination:
server: https://kubernetes.default.svc
namespace: neuron-tim
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=false
@@ -0,0 +1,14 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: neuron-tim-config
namespace: neuron-tim
data:
SPRING_PROFILES_ACTIVE: "prod"
NEURON_DATA_DIR: "/data"
NEURON_DB_PATH: "/data/neuron.db"
NEURON_STORAGE_PATH: "/data"
SERVER_TOMCAT_ACCESSLOG_ENABLED: "true"
# Prod-equivalent: minimal surface — never expose internals
MANAGEMENT_ENDPOINTS_WEB_EXPOSURE_INCLUDE: "health,info"
MANAGEMENT_ENDPOINT_HEALTH_SHOW_DETAILS: "never"
@@ -0,0 +1,57 @@
# ExternalSecret for Tim's Neuron instance.
#
# Before Tim's instance can start, populate these Vault paths:
# vault kv put secret/neuron-technologies/tim \
# api_key=<Tim's NEURON_API_KEY> \
# gitea_webhook_secret=<Tim's webhook secret>
#
# Required Vault secrets:
# secret/data/neuron-technologies/tim:
# - api_key → NEURON_API_KEY
# - gitea_webhook_secret → NEURON_WEBHOOK_SECRET
#
# secret/data/neuron-technologies/license:
# - admin_token → NEURON_LICENSE_ADMIN_TOKEN (shared with prod)
#
# secret/data/neuron-technologies/unkey:
# - root_key → UNKEY_ROOT_KEY (shared with prod)
# - api_id → UNKEY_API_ID (shared with prod)
#
# Tim's instance-specific secrets that should be scoped under secret/neuron-technologies/tim:
# - anthropic_api_key (Tim's own Anthropic API key)
# - neuron_license_key (Tim's license key issued by the license server)
# - db_encryption_key (encryption key for Tim's SQLite DB)
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: neuron-tim-secrets
namespace: neuron-tim
spec:
refreshInterval: 1h
secretStoreRef:
name: vault
kind: ClusterSecretStore
target:
name: neuron-tim-secrets
creationPolicy: Owner
data:
- secretKey: NEURON_API_KEY
remoteRef:
key: secret/data/neuron-technologies/tim
property: api_key
- secretKey: NEURON_WEBHOOK_SECRET
remoteRef:
key: secret/data/neuron-technologies/tim
property: gitea_webhook_secret
- secretKey: NEURON_LICENSE_ADMIN_TOKEN
remoteRef:
key: secret/data/neuron-technologies/license
property: admin_token
- secretKey: UNKEY_ROOT_KEY
remoteRef:
key: secret/data/neuron-technologies/unkey
property: root_key
- secretKey: UNKEY_API_ID
remoteRef:
key: secret/data/neuron-technologies/unkey
property: api_id
@@ -0,0 +1,37 @@
# TODO: Confirm subdomain for Tim's Neuron instance.
# Placeholder: tim.neurontechnologies.ai
# Alternatives to consider: neuron-tim.neuralplatform.ai
# Once confirmed, add a DNS CNAME record in dns-neurontechnologies.tf (or dns-neuralplatform.tf)
# pointing to ${var.cloudflare_tunnel_id}.cfargotunnel.com.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: neuron-tim
namespace: neuron-tim
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: websecure
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
ingressClassName: traefik
tls:
- secretName: neuron-tim-tls
hosts:
- tim.neurontechnologies.ai
rules:
- host: tim.neurontechnologies.ai
http:
paths:
- path: /mcp
pathType: Prefix
backend:
service:
name: neuron-mcp
port:
number: 8080
- path: /
pathType: Prefix
backend:
service:
name: neuron-rest
port:
number: 8081
@@ -0,0 +1,10 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- configmap.yaml
- pvc.yaml
- externalsecret.yaml
- mcp-deployment.yaml
- rest-deployment.yaml
- services.yaml
- ingress.yaml
@@ -0,0 +1,61 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: neuron-mcp
namespace: neuron-tim
labels:
app: neuron-mcp
env: tim
spec:
replicas: 0 # Not yet deployed — Tim's imprint not set up
strategy:
type: Recreate
selector:
matchLabels:
app: neuron-mcp
template:
metadata:
labels:
app: neuron-mcp
env: tim
spec:
containers:
- name: neuron-mcp
image: registry.neuralplatform.ai/neuron-technologies/neuron-mcp:v0.6.1
imagePullPolicy: Always
ports:
- name: http
containerPort: 8080
envFrom:
- configMapRef:
name: neuron-tim-config
- secretRef:
name: neuron-tim-secrets
volumeMounts:
- name: data
mountPath: /data
resources:
requests:
cpu: 250m
memory: 512Mi
limits:
cpu: 1000m
memory: 1Gi
livenessProbe:
httpGet:
path: /actuator/health/liveness
port: http
initialDelaySeconds: 30
periodSeconds: 30
failureThreshold: 3
readinessProbe:
httpGet:
path: /actuator/health/readiness
port: http
initialDelaySeconds: 15
periodSeconds: 10
failureThreshold: 3
volumes:
- name: data
persistentVolumeClaim:
claimName: neuron-tim-data
@@ -0,0 +1,12 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: neuron-tim-data
namespace: neuron-tim
spec:
storageClassName: local-path
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
@@ -0,0 +1,61 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: neuron-rest
namespace: neuron-tim
labels:
app: neuron-rest
env: tim
spec:
replicas: 0 # Not yet deployed — Tim's imprint not set up
strategy:
type: Recreate
selector:
matchLabels:
app: neuron-rest
template:
metadata:
labels:
app: neuron-rest
env: tim
spec:
containers:
- name: neuron-rest
image: registry.neuralplatform.ai/neuron-technologies/neuron-rest:v0.6.1
imagePullPolicy: Always
ports:
- name: http
containerPort: 8081
envFrom:
- configMapRef:
name: neuron-tim-config
- secretRef:
name: neuron-tim-secrets
volumeMounts:
- name: data
mountPath: /data
resources:
requests:
cpu: 250m
memory: 512Mi
limits:
cpu: 1000m
memory: 1Gi
livenessProbe:
httpGet:
path: /actuator/health/liveness
port: http
initialDelaySeconds: 30
periodSeconds: 30
failureThreshold: 3
readinessProbe:
httpGet:
path: /actuator/health/readiness
port: http
initialDelaySeconds: 15
periodSeconds: 10
failureThreshold: 3
volumes:
- name: data
persistentVolumeClaim:
claimName: neuron-tim-data
@@ -0,0 +1,31 @@
apiVersion: v1
kind: Service
metadata:
name: neuron-mcp
namespace: neuron-tim
labels:
app: neuron-mcp
spec:
selector:
app: neuron-mcp
ports:
- name: http
port: 8080
targetPort: 8080
type: ClusterIP
---
apiVersion: v1
kind: Service
metadata:
name: neuron-rest
namespace: neuron-tim
labels:
app: neuron-rest
spec:
selector:
app: neuron-rest
ports:
- name: http
port: 8081
targetPort: 8081
type: ClusterIP
+13
View File
@@ -37,3 +37,16 @@ resource "kubernetes_namespace" "neuron_prod" {
}
}
}
resource "kubernetes_namespace" "neuron_tim" {
metadata {
name = "neuron-tim"
labels = {
managed-by = "terraform"
tier = "apps"
environment = "prod"
app = "neuron-technologies"
owner = "tim"
}
}
}