BYOC Deployment Runlist

For each cluster in your turbopuffer BYOC deployment, you will be provided with a 'BYOC kit' containing all the files required to configure your cluster. This document provides guidance for successfully deploying a new turbopuffer BYOC cluster.

Your kit contents

byoc-kit
├── README.md
├── aws
│   ├── main.tf
│   └── turbopuffer.tfvars
├── cosign.pub
├── gcp
│   ├── main.tf
│   └── turbopuffer.tfvars
├── azure
│   ├── main.tf
│   └── turbopuffer.tfvars
├── scripts
│   ├── generate_secrets.py
│   └── sanity.sh
├── values.yaml (generated) # configuration file generated by Terraform
├── values.secret.yaml (generated) # sensitive configuration file generated by Terraform
├── compute_classes.yaml (generated, GCP only) # GKE ComputeClass manifest generated by Terraform
└── metrics-keys.yaml # configuration file provided by turbopuffer

Runlist

  1. Mise en place: Check you have all prerequisites:
    • Verify you have terraform, kubectl, and helm installed.
    • Provision a fresh sub-account / project for your new cluster.
    • Enable your cluster to pull images from our registries: Provide the service account email used for pulling images to the turbopuffer team. Use either the default compute service account for the sub-account or a custom service account, such as one used to replicate images into your own registry or configured in Kubernetes.
  2. Cluster configuration: Apply the Terraform configuration to set up the Kubernetes cluster and bucket.
    • cd gcp
    • Run terraform init to set up the required providers.
    • Fill in the required values in turbopuffer.tfvars. The query_skus, index_skus, and maintenance_machine_type variables control which GCP machine types back the query, index, and maintenance node pools. The defaults work for most deployments.
    • Apply the Terraform configuration: terraform apply -var-file=turbopuffer.tfvars
  3. Configure kubectl: Add your new cluster context to kubectl.
    • Run gcloud container clusters get-credentials CLUSTER_NAME --project PROJECT_ID --region REGION
    • Run kubectl config get-contexts and confirm the context is correct.
    • Run kubectl get pods and confirm the command succeeds (no output).
    • Apply ComputeClass manifests: Terraform writes a compute_classes.yaml at the kit root that defines GKE ComputeClass priorities across the query and index node pools. Apply it before installing Helm so the autoscaler has the priority order in place when the first pods schedule: kubectl apply -f compute_classes.yaml
  4. Configure Helm: The Terraform command will have generated a values.yaml file in the byoc-kit directory, which contains values for Helm. Edit this file and set any other necessary values. Refer to values.schema.json for a description of valid configurations.
  5. Generate API keys: Run ./scripts/generate_secrets.py to generate values.secret.yaml. The script will generate an org ID and API key, along with a token for intra-cluster communication.
  6. Deploy turbopuffer:
    • Log in to the Helm registry: Run helm registry login us-central1-docker.pkg.dev
    • Install the Helm chart: Run helm install -n default turbopuffer oci://us-central1-docker.pkg.dev/turbopuffer-onprem/charts/tpuf --values=values.yaml --values=values.secret.yaml --values=metrics-keys.yaml
    • For subsequent updates, run helm upgrade -n default turbopuffer oci://us-central1-docker.pkg.dev/turbopuffer-onprem/charts/tpuf --values=values.yaml --values=values.secret.yaml --values=metrics-keys.yaml
  7. Run post-deployment sanity checks
    • TURBOPUFFER_API_KEY=<your_api_key> scripts/sanity.sh will query your turbopuffer cluster directly, verifying that core operations function. It will not verify certificates and may encounter a 500 error if the nodes aren't routable yet.

Using a custom registry for your turbopuffer cluster

By default, turbopuffer will pull from one of several turbopuffer-managed image registries, as configured in our included Terraform. However, there are many reasons you may want to host our images in a registry you control. Our Helm chart fully supports this through the following settings:

image.registry: YOUR_REGISTRY_URL
control_plane.image.registry: YOUR_REGISTRY_URL

We expect that registry to contain two repositories, turbopuffer and tpuf-ctl-cluster, to hold the images for turbopuffer and our control plane agent, respectively.

For customers on AWS, we can configure ECR Replication to automatically push the latest images into your registry.

Using cloud-provider-managed TLS certificates

Our Helm chart supports configuring TLS termination within your cluster using either cert-manager or native Kubernetes APIs. Your organization may already manage certificates through your cloud provider's managed certificate offering. In that case, you will need to handle TLS termination yourself.

Regardless of your cloud provider, you will want to deploy turbopuffer internally by setting:

ingress.internal: true

GCP

To get started, set the following in values.yaml and rerun helm upgrade ... as described in step 5.

certificates.mode: disabled

Adding Google Managed Certificates to your GKE cluster is as simple as deploying the following Kubernetes manifest alongside your turbopuffer Helm deployment. All that is required is to insert the correct value for YOUR_DOMAIN.

apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
  name: ingress-nginx-svc-config
  namespace: ingress-nginx
spec:
  healthCheck:
    checkIntervalSec: 10
    timeoutSec: 10
    port: 80
    type: HTTP
    requestPath: /healthz

---
apiVersion: v1
kind: Service
metadata:
  name: ingress-nginx-svc
  namespace: ingress-nginx
  annotations:
    cloud.google.com/backend-config: '{"default": "ingress-nginx-svc-config"}'
spec:
  ports:
  - appProtocol: http
    name: http
    port: 80
    protocol: TCP
    targetPort: http
  - appProtocol: https
    name: https
    port: 443
    protocol: TCP
    targetPort: https
  selector:
    app.kubernetes.io/component: controller
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/name: ingress-nginx
  type: ClusterIP
---
apiVersion: networking.gke.io/v1
kind: ManagedCertificate
metadata:
  name: managed-cert
  namespace: ingress-nginx
spec:
  domains:
    - YOUR_DOMAIN
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-nginx-ing
  namespace: ingress-nginx
  annotations:
    networking.gke.io/managed-certificates: managed-cert
spec:
  ingressClassName: "gce"
  defaultBackend:
    service:
      name: ingress-nginx-svc
      port:
        number: 80

Networking

If you want to disable outgoing connections for the cluster, you can allowlist the following IPs:

  • Polar Signals (CPU and Heap profiling)
    • 35.234.93.182 (api.polarsignals.com)
  • Control Plane (Cluster Heartbeats)
    • 34.8.199.114/32
  • Datadog (Telemetry)
    • curl -s https://ip-ranges.us5.datadoghq.com/ | jq -r '(.agents.prefixes_ipv4 + .api.prefixes_ipv4 + .apm.prefixes_ipv4 + .global.prefixes_ipv4 + .logs.prefixes_ipv4 + .orchestrator.prefixes_ipv4 + .process.prefixes_ipv4 + .["remote-configuration"].prefixes_ipv4) | unique[]'
    • Note: turbopuffer reports to the us5 Datadog site, so the ranges must come from ip-ranges.us5.datadoghq.com. These ranges can change over time; if your firewall supports FQDN rules, allowing *.us5.datadoghq.com on 443 is more durable.

Upgrading turbopuffer versions

If you have manual approvals enabled, the turbopuffer team will provide you with a command to upgrade the cluster when a new version is available. Otherwise, upgrades will happen automatically through the control plane.