Deploy the dataplane
If you have not yet set up the required resources (Kubernetes cluster, object storage, container registry, credentials), see Prepare infrastructure first.
This page covers the single-cluster path: one cluster in the default cluster pool, as created by the flyte create cluster ... --pool default command below. If you plan to connect several clusters to the same control plane, read
Multiple clusters first. Pool membership governs metadata sharing: clusters in the same pool share one metadata bucket, and clusters in different pools must use different ones, so it affects the metadata bucket you configure below.
Assumptions
- You have a Union.ai organization, and you know the control plane URL for your organization (e.g.
https://your-org-name.us-east-2.unionai.cloud). - You have a cluster name provided by or coordinated with Union.
- You have a Kubernetes cluster, running one of the most recent three minor Kubernetes versions. Learn more.
- Object storage provided by a vendor or an S3-compatible platform (such as MinIO), with CORS configured as described in Prepare infrastructure.
- A container registry accessible from your cluster.
Prerequisites
- Install Helm 3.
- Install uctl.
- Install the
flyteCLI. - Install the
flyteplugins-unionplugin, which provides theflyte create clusterandflyte get clustercommands:pip install flyteplugins-union.
Deploy the Union.ai operator
-
Add the Union.ai Helm repo:
helm repo add unionai https://unionai.github.io/helm-charts/ helm repo update -
Configure the
flyteCLI to talk to your control plane, then register the cluster name:flyte create config --endpoint <YOUR_UNION_CONTROL_PLANE_URL> --org <YOUR_ORG_NAME> flyte create cluster <YOUR_SELECTED_CLUSTERNAME> --pool defaultflyte create configwrites.flyte/config.yaml. The first command that contacts the control plane opens a browser to authenticate you.The second command registers the cluster before you install the chart: the data plane binds to this record when it starts. Every organization is provisioned with a
defaultpool, so--pool defaultneeds no extra setup. -
Use the
uctl selfserve provision-dataplane-resourcescommand to generate a new client and client secret for communicating with your Union control plane, provision authorization permissions for the app to operate on the Union cluster name you have selected, and provide follow-up instructions:uctl config init --host=<YOUR_UNION_CONTROL_PLANE_URL> uctl selfserve provision-dataplane-resources --clusterName <YOUR_SELECTED_CLUSTERNAME> --provider custom-
The command will output the ID, name, and a secret that will be used by the Union services to communicate with your control plane. You will pass the client ID and client secret to the Helm chart in step 5.
-
Save the secret that is displayed. Union does not store it, and it cannot be retrieved later.
-
-
Download the base values file for the data plane chart and fill in your infrastructure details:
curl -O https://raw.githubusercontent.com/unionai/helm-charts/main/charts/dataplane/values.yamlThe published overlays cover AWS, GCP, and Azure only, so a generic or on-premise environment starts from the base values file:
- Set
global.UNION_CONTROL_PLANE_HOSTandglobal.CONTROLPLANE_HOSTto your control plane hostname (no scheme, no port). - Set
global.CLUSTER_NAMEto the cluster name you registered in step 2. - Set
global.ORG_NAMEto your organization name. - Set
storage.endpointto your S3-compatible storage endpoint (e.g. your MinIO URL). - Set
storage.bucketNameandstorage.fastRegistrationBucketNameto your bucket name(s). - Set
storage.regionto the region of your storage provider. - The same credentials are also needed in
fluentbit.envfor log shipping.
Rather than putting your storage credentials in the values file, store them in a Kubernetes Secret and reference it from the chart. Create the namespace and the secret first; the chart reads the secret while rendering, so it must exist before you install:
kubectl create namespace union kubectl create secret generic storage-credentials -n union \ --from-literal=access_key_id=<ACCESS_KEY_ID> \ --from-literal=secret_key=<SECRET_ACCESS_KEY>Then reference it instead of setting
storage.accessKeyandstorage.secretKey:storage: provider: compat authType: accesskey credentialsSecretRef: name: storage-credentialsThe chart resolves the secret with a Helm
lookup, which returns nothing duringhelm templateor--dry-run. Those commands render the storage config without credentials; only a real install picks them up. If your secret uses different field names, setcredentialsSecretRef.accessKeyIdKeyandcredentialsSecretRef.secretKeyKeyto match. - Set
-
Install the data plane Helm chart, passing the client ID and client secret from step 3:
helm upgrade --install union unionai/dataplane \ -f values.yaml \ --set global.AUTH_CLIENT_ID=<CLIENT_ID> \ --set-string secrets.admin.clientId=<CLIENT_ID> \ --set secrets.admin.clientSecret=<CLIENT_SECRET> \ --namespace union \ --create-namespace -
Once deployed you can check to see if the cluster has been successfully registered to the control plane:
flyte get clusterThe command groups clusters by state. A successfully registered cluster appears under Enabled Clusters:
Enabled Clusters NAME ORG STATE HEALTH <cluster> <org> enabled healthy -
Follow the Quickstart to run your first workflow and verify your cluster is working correctly.
Next: manage your cluster and pools
uctl selfserve provision-dataplane-resources provisions the data plane and
registers this cluster with the control plane. Once it is connected, you manage
the cluster pool it belongs to, and route work to it with queues, from the
Cluster and workload management
user guide:
- Cluster pools: group clusters that share one data plane (object store, secrets, registry).
- Clusters: inspect and manage the cluster records registered with the control plane.
- Managing queues: route workloads to a pool and enforce concurrency, priority, and fairness.
Each cluster is assigned exactly one pool. If no custom pool is specified when the
cluster is created, it joins the default pool that every organization is
provisioned with, so a single-cluster deployment needs no extra pool setup.