DevOps / DataOps Engineer
You own: CI/CD, Helm, GitOps, secret rotation, image signing. You make GeneFlow ship safely + fast.
What's new for you
| Was | Now in GeneFlow |
|---|---|
| Bespoke deploy pipelines per service | Standard Helm chart infrastructure/k8s/helm/genedata/ covers everything |
| Manual K8s manifests for ML | Auto-reconciled by jobs-service deployer |
| Secrets in CI vars | External Secrets Operator → AWS/GCP Secrets Manager |
| Grafana dashboards JSON in S3 | ConfigMap + sidecar auto-loads |
Day-1 setup
# Helm install
helm upgrade --install genedata ./infrastructure/k8s/helm/genedata \
--set image.tag=$IMAGE_SHA \
--set global.agentRuntime.enabled=true \
--set global.modelServing.enabled=true \
--set observability.grafanaDashboards.enabled=true \
--set observability.prometheusRules.enabled=true
# ArgoCD if you use it
kubectl apply -f infrastructure/argocd/apps/genedata.yaml
Workflow 1 — Ship a release
- Merge to
main→ Bitbucket Pipelines builds + tests + scans - CI tags
<service>:<sha>and pushes toregistry.genedata.io - ArgoCD sees the new Helm values and reconciles
- PromoteCriteria gates dictate when staging → prod (see PROMOTION_CRITERIA.md)
Smoke check post-deploy:
gfctl experiments list # tracking works
gfctl endpoints list # serving works
gfctl prompts list # registry works
kubectl get pods -l app.kubernetes.io/component=model-serving # serving pods healthy
Workflow 2 — Rotate the system token
# 1. Issue new token in AWS Secrets Manager (or your secrets backend)
aws secretsmanager update-secret --secret-id genedata/jobs-system-token \
--secret-string "$(genedata auth issue-system-token --scope internal:ingest)"
# 2. ESO syncs into K8s Secret geneflow-runner-secrets automatically
# 3. Rolling restart the deployments that envFrom it
kubectl rollout restart deploy/jobs-service deploy/geneflow-service -n genedata
Workflow 3 — Add a Helm value with safe defaults
The pattern: every new feature ships disabled by default under a top-level toggle. Example:
global:
modelServing:
enabled: false # opt-in
deployerServiceAccount: jobs-service
Then guard the templates: {{- if .Values.global.modelServing.enabled }}.
Workflow 4 — Sign serving images (cosign)
# In CI
cosign sign --key cosign.key registry.genedata.io/geneflow/fraud-detector:v3
# Helm enforces verification via policy controller
helm upgrade ... \
--set serving.imagePolicy=enforce \
--set serving.imagePolicy.publicKey=$(cat cosign.pub)
Workflow 5 — Roll a new Grafana dashboard out
- Drop JSON into
infrastructure/observability/grafana/dashboards/ - Reference it in
templates/observability/grafana-dashboards.yaml:
``yaml data: my-new-dashboard.json: |- {{ .Files.Get "../../observability/grafana/dashboards/my-new-dashboard.json" | indent 4 }} ``
helm upgrade— sidecar picks it up, appears in Grafana folder
Workflow 6 — Backups + observability are part of CI
# bitbucket-pipelines.yml step
- step:
name: Verify backups exist
script:
- wal-g backup-list | grep "$(date -u +%Y-%m-%d)" || exit 1
services: [postgres]
Common gotchas
- Never skip pre-commit hooks (
--no-verify) — they enforce migrations are forward-only, Helm renders cleanly, etc. - Don't hard-code namespace — use
{{ .Release.Namespace }}everywhere. - The migration
0015_geneflow_collab.sqlmust run BEFORE you enable the collab editor toggle — order matters. - Pre-quantum SSH warning to Bitbucket is informational only; not a real failure.
Where to go next
- 13-sre.md — on-call
- 11-data-platform-engineer.md — storage / k8s
- docs/CI_AND_DEPLOYMENT.md