Add Helm chart for spur-cloud deployment#62
Open
yansun1996 wants to merge 1 commit into
Open
Conversation
Wraps the existing deploy/k8s manifests into a configurable Helm chart at deploy/helm/spur-cloud. Renders the full spur-cloud.toml into a Secret (removing the CHANGEME placeholder leak), parameterizes image refs and ingress, and adds optional in-cluster Postgres / existing-secret support for ExternalSecrets workflows. Co-Authored-By: Claude Opus 4 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Adds a first-class Helm chart under deploy/helm/spur-cloud/ to deploy Spur Cloud’s control plane (API + frontend) with optional in-cluster Postgres, ingress, session namespace management, and RBAC, replacing the current “apply raw manifests” workflow with configurable Helm values and upgrade semantics.
Changes:
- Introduces a chart skeleton (
Chart.yaml,values.yaml,.helmignore) and end-user docs (README.md,NOTES.txt). - Adds templates for API + frontend Deployments/Services, Ingress routing, optional Postgres StatefulSet/headless Service, and session Namespace retention.
- Renders
spur-cloud.tomlinto a Secret (with optionalsecrets.existingSecretsupport) and wires it into the API pod.
Reviewed changes
Copilot reviewed 13 out of 13 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| deploy/helm/spur-cloud/Chart.yaml | Defines the spur-cloud Helm chart metadata. |
| deploy/helm/spur-cloud/values.yaml | Provides configurable defaults for images, ingress, config, secrets, RBAC, and Postgres. |
| deploy/helm/spur-cloud/README.md | Documents installation and configuration patterns (including external DB / existing secret). |
| deploy/helm/spur-cloud/.helmignore | Standard Helm packaging ignore patterns. |
| deploy/helm/spur-cloud/templates/_helpers.tpl | Naming/label helpers and DB URL rendering helpers. |
| deploy/helm/spur-cloud/templates/secret.yaml | Creates the Secret containing spur-cloud.toml (+ db password material). |
| deploy/helm/spur-cloud/templates/api.yaml | Deploys the API and mounts the rendered config Secret; includes rollout checksum. |
| deploy/helm/spur-cloud/templates/frontend.yaml | Deploys the frontend Service + Deployment. |
| deploy/helm/spur-cloud/templates/ingress.yaml | Routes /api to API and / to frontend. |
| deploy/helm/spur-cloud/templates/postgres.yaml | Optional in-cluster Postgres StatefulSet + headless Service. |
| deploy/helm/spur-cloud/templates/rbac.yaml | ServiceAccount and ClusterRole/ClusterRoleBinding. |
| deploy/helm/spur-cloud/templates/session-namespace.yaml | Optional retained session namespace creation. |
| deploy/helm/spur-cloud/templates/NOTES.txt | Post-install guidance and reminders. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| enabled: false | ||
| secretName: "" | ||
|
|
||
| # Application config rendered into the ConfigMap as spur-cloud.toml. |
Comment on lines
+56
to
+62
| {{- define "spur-cloud.secretName" -}} | ||
| {{- if .Values.secrets.existingSecret -}} | ||
| {{- .Values.secrets.existingSecret -}} | ||
| {{- else -}} | ||
| {{ include "spur-cloud.fullname" . }}-secrets | ||
| {{- end -}} | ||
| {{- end -}} |
| {{- if not .Values.secrets.dbPassword -}} | ||
| {{- fail "secrets.dbPassword must be set when postgres.enabled is true and secrets.existingSecret is unused" -}} | ||
| {{- end -}} | ||
| {{- printf "postgresql://%s:%s@%s:5432/%s" .Values.postgres.user .Values.secrets.dbPassword (include "spur-cloud.postgres.fullname" .) .Values.postgres.database -}} |
Comment on lines
+55
to
+57
| {{- if and .Values.postgres.enabled (not .Values.database.url) }} | ||
| db-password: {{ .Values.secrets.dbPassword | quote }} | ||
| {{- end }} |
Comment on lines
+1
to
+4
| {{- if .Values.secrets.create -}} | ||
| {{- if not .Values.secrets.jwtSecret -}} | ||
| {{- fail "secrets.jwtSecret is required (generate with: openssl rand -hex 32) — or set secrets.existingSecret and secrets.create=false" -}} | ||
| {{- end -}} |
Comment on lines
+12
to
+15
| {{- end }} | ||
| {{- if .Values.rbac.create }} | ||
| --- | ||
| apiVersion: rbac.authorization.k8s.io/v1 |
shiv-tyagi
suggested changes
Jun 6, 2026
| enabled: true | ||
| replicas: 2 | ||
| image: | ||
| repository: ghcr.io/rocm/spur-cloud-api |
Member
There was a problem hiding this comment.
We don't have these images yet. This can be misleading.
| name: spur-cloud | ||
| description: GPU as a Service platform built on Spur. Deploys the API, frontend, optional in-cluster Postgres, RBAC, and ingress. | ||
| type: application | ||
| version: 0.1.0 |
Member
There was a problem hiding this comment.
Suggested change
| version: 0.1.0 | |
| version: 0.0.1-dev |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #61
Summary
deploy/helm/spur-cloud/wrapping the existing K8s manifests.spur-cloud.tomlrendered into a Secret (removes the existing ConfigMap leak ofjwt_secretand theCHANGEMEplaceholder).secrets.existingSecretescape hatch for ExternalSecrets / sealed-secrets workflows.checksum/secretannotation on the API pod so config changes trigger a rollout.ghcr.io/rocm/spur-cloud-{api,frontend}(override via values); pull-policy and pull-secrets are wired through.app.kubernetes.io/*labels and release-prefixed names so multiple instances can coexist.helm.sh/resource-policy: keepsohelm uninstalldoes not delete running user pods.clusterIP: None(proper headless service for the StatefulSet),PGDATAset to a subdir to avoid thelost+foundfirst-boot gotcha, plus apg_isreadyreadiness probe.Verification
helm lint deploy/helm/spur-cloud --set secrets.jwtSecret=test --set secrets.dbPassword=test— clean (only the "icon is recommended" info).helm template ...renders with auth providers on/off; required-secret guards (jwtSecret,dbPassword,githubClientSecret,oktaClientSecret) fail loudly when missing.How to try it
External Postgres:
Out of scope (tracked in #61 follow-ups)
dependencies:on a futurespurchart so--set spur.enabled=truebrings up the whole stack.deploy/k8s/*.yamlor regenerate them fromhelm templatein CI.Test plan
helm lintpasseshelm templaterenders with defaults + auth providers + existing-secret + external-DB modeshelm installon a real cluster (reviewer)helm upgradewith a changedconfig.publicUrlrolls API pods (checksum annotation)