# Orchestrator Kubernetes Deployment # Supports 4 deployment modes: solo, multiuser, cicd, enterprise # Exports to YAML via: nickel export --format json | yq -P # # Usage: # nickel eval --format json orchestrator-deployment.yaml.ncl | yq -P > orchestrator-deployment.yaml # kubectl apply -f orchestrator-deployment.yaml { apiVersion = "apps/v1", kind = "Deployment", metadata = { name = "orchestrator", labels = { app = "orchestrator", component = "provisioning-platform", }, }, spec = { # Solo: 1 replica (single developer) # MultiUser: 1 replica (team development) # CI/CD: 1 replica (stateless, ephemeral) # Enterprise: 3 replicas (HA with load balancing) replicas = 3, # Override per mode selector = { matchLabels = { app = "orchestrator", }, }, template = { metadata = { labels = { app = "orchestrator", component = "provisioning-platform", }, annotations = { "prometheus.io/scrape" = "true", "prometheus.io/port" = "9090", "prometheus.io/path" = "/metrics", }, }, spec = { # Service account for orchestrator serviceAccountName = "orchestrator", # Init container: wait for dependencies initContainers = [ { name = "wait-for-storage", image = "busybox:1.35", command = ["sh", "-c", "until wget -q http://storage-service:8000/health || true; do echo waiting; sleep 2; done"], imagePullPolicy = "IfNotPresent", }, ], containers = [ { name = "orchestrator", image = "provisioning-orchestrator:latest", imagePullPolicy = "Always", ports = [ { name = "http", containerPort = 9090, protocol = "TCP", }, { name = "metrics", containerPort = 9091, protocol = "TCP", }, ], env = [ { name = "ORCHESTRATOR_MODE", value = "kubernetes", }, { name = "ORCHESTRATOR_SERVER_HOST", value = "0.0.0.0", }, { name = "ORCHESTRATOR_SERVER_PORT", value = "9090", }, { name = "ORCHESTRATOR_STORAGE_BACKEND", valueFrom = { configMapKeyRef = { name = "orchestrator-config", key = "storage_backend", }, }, }, { name = "ORCHESTRATOR_STORAGE_PATH", value = "/var/lib/provisioning/orchestrator/data", }, { name = "ORCHESTRATOR_QUEUE_MAX_CONCURRENT_TASKS", valueFrom = { configMapKeyRef = { name = "orchestrator-config", key = "max_concurrent_tasks", }, }, }, { name = "ORCHESTRATOR_BATCH_PARALLEL_LIMIT", valueFrom = { configMapKeyRef = { name = "orchestrator-config", key = "batch_parallel_limit", }, }, }, { name = "ORCHESTRATOR_LOG_LEVEL", valueFrom = { configMapKeyRef = { name = "orchestrator-config", key = "log_level", }, }, }, { name = "POD_NAME", valueFrom = { fieldRef = { fieldPath = "metadata.name", }, }, }, { name = "POD_NAMESPACE", valueFrom = { fieldRef = { fieldPath = "metadata.namespace", }, }, }, ], # Health check: HTTP GET /health on port 9090 livenessProbe = { httpGet = { path = "/health", port = 9090, }, initialDelaySeconds = 30, periodSeconds = 10, timeoutSeconds = 5, failureThreshold = 3, }, # Startup check: ensure service is ready readinessProbe = { httpGet = { path = "/health", port = 9090, }, initialDelaySeconds = 20, periodSeconds = 5, timeoutSeconds = 3, failureThreshold = 3, }, # Resource management resources = { requests = { cpu = "500m", # Minimum 0.5 CPU memory = "512Mi", # Minimum 512MB }, limits = { cpu = "2", # Maximum 2 CPUs memory = "2Gi", # Maximum 2GB }, }, # Volume mounts volumeMounts = [ { name = "orchestrator-data", mountPath = "/var/lib/provisioning/orchestrator/data", }, { name = "orchestrator-logs", mountPath = "/var/log/provisioning/orchestrator", }, ], # Security context securityContext = { allowPrivilegeEscalation = false, runAsNonRoot = true, runAsUser = 1000, capabilities = { drop = ["ALL"], }, }, }, ], # Volumes volumes = [ { name = "orchestrator-data", persistentVolumeClaim = { claimName = "orchestrator-data", }, }, { name = "orchestrator-logs", persistentVolumeClaim = { claimName = "orchestrator-logs", }, }, ], # Pod affinity for distributed deployment (enterprise mode) affinity = { podAntiAffinity = { preferredDuringSchedulingIgnoredDuringExecution = [ { weight = 100, podAffinityTerm = { labelSelector = { matchExpressions = [ { key = "app", operator = "In", values = ["orchestrator"], }, ], }, topologyKey = "kubernetes.io/hostname", }, }, ], }, }, # Tolerations for node failures tolerations = [ { key = "node.kubernetes.io/not-ready", operator = "Exists", effect = "NoExecute", tolerationSeconds = 300, }, { key = "node.kubernetes.io/unreachable", operator = "Exists", effect = "NoExecute", tolerationSeconds = 300, }, ], # Restart policy restartPolicy = "Always", # Termination grace period terminationGracePeriodSeconds = 30, }, }, # Deployment strategy strategy = { type = "RollingUpdate", rollingUpdate = { maxSurge = 1, maxUnavailable = 0, }, }, # Rollback configuration revisionHistoryLimit = 5, }, }