Connect clusters with separate Kubernetes and cloud owners
Connect a cluster when the Kubernetes team and the cloud team have separate access: the Kubernetes team runs castctl cluster connect --k8s-only first, then the cloud team registers cloud credentials via the Cast AI API.
In many organizations, access is split: one team manages the Kubernetes cluster, and another team manages the cloud account. Cast AI supports this workflow:
- Kubernetes team connects the cluster with
castctl cluster connect --k8s-only. This installs only the in-cluster Cast AI components; no cloud-side resources are created and the cluster runs in read-only mode (Cost Monitoring). - Cloud team provisions the required cloud resources and registers the credentials with the Cast AI API, without needing access to the Kubernetes cluster.
- The cluster starts to reconcile and ends up connected — Node Autoscaling becomes available.
The cloud team needs only a Cast AI API key and the cluster ID (an org admin or the Kubernetes team can provide both).
NoteThe steps below cover the manual API flow. If both parts can run from one identity, simply re-running
castctl cluster connectwithout--k8s-onlyperforms the whole cloud setup automatically — pass--gcp-credential-method impersonation(GKE) or--azure-credential-method impersonation(AKS) to use impersonation.
Step 1 (Kubernetes team): connect with --k8s-only
--k8s-onlyRun:
castctl cluster connect --k8s-onlyThen hand the cluster ID and a Cast AI API key to the cloud team.
Step 2 (Cloud team): register cloud credentials
Follow the section for your provider.
EKS: cross-account IAM role
-
Get the Cast AI jumper role ARN:
curl -s -H "Authorization: Bearer <API key>" \ "<API root URL>/v1/kubernetes/external-clusters/<cluster ID>/assume-role-user" -
Create an IAM role in your AWS account. Allow the Cast AI jumper role to assume it and grant it the required permissions (see Cloud permissions).
-
Upload the IAM role to Cast AI:
curl -s -H "Authorization: Bearer <API key>" -X POST \ "<API root URL>/v1/kubernetes/external-clusters/<cluster ID>" \ -d '{"eks":{"assumeRoleArn":"<your IAM role ARN>"}}' -
Create a node configuration. Since
--k8s-onlydoes not create the Cast AI instance profile, point the configuration at your own existing instance profile:curl -s -H "Authorization: Bearer <API key>" -X POST \ "<API root URL>/v1/kubernetes/clusters/<cluster ID>/node-configurations" \ -d '{ "name": "default", "subnets": ["<subnet ID>"], "eks": { "securityGroups": ["<security group ID>"], "instanceProfileArn": "<instance profile ARN>" } }'WarningThe role inside your instance profile must be authorized in the EKS cluster (EKS access entry or the
aws-authConfigMap), or nodes will fail to join. Cast AI manages this entry only for its own default role. This step requires Kubernetes access — coordinate with the Kubernetes team. -
Set the node configuration as default:
curl -s -H "Authorization: Bearer <API key>" -X POST \ "<API root URL>/v1/kubernetes/clusters/<cluster ID>/node-configurations/<node config ID>/default"
GKE: service account impersonation
Cast AI's organization-level impersonation service account impersonates a service account in your project using short-lived tokens. See GKE service account impersonation for background.
-
Get the Cast AI service account that will impersonate your service account:
curl -s -H "Authorization: Bearer <API key>" -X POST \ "<API root URL>/v1/kubernetes/external-clusters/impersonation-service-account" \ -d '{"provider":"gke"}'Save the
emailfrom the response. -
Create a GCP service account that Cast AI will impersonate and grant it the necessary permissions (see Cloud permissions).
-
Allow the Cast AI service account to impersonate your service account:
gcloud iam service-accounts add-iam-policy-binding "<your SA email>" \ --member="serviceAccount:<Cast SA email>" \ --role="roles/iam.serviceAccountUser" \ --condition="title=SpecificServiceAccountCondition,description=Allow impersonation only for CASTAI_SERVICE_ACCOUNT,expression=request.auth.claims.email == \"<Cast SA email>\"" \ --project "<GCP project ID>" gcloud iam service-accounts add-iam-policy-binding "<your SA email>" \ --member="serviceAccount:<Cast SA email>" \ --role="roles/iam.serviceAccountTokenCreator" \ --condition="title=AlwaysTrueCondition,description=This condition is always true,expression=true" \ --project "<GCP project ID>"GCP IAM bindings can take a few minutes to propagate.
-
Upload your service account details to Cast AI (both fields must be set together):
curl -s -H "Authorization: Bearer <API key>" -X POST \ "<API root URL>/v1/kubernetes/external-clusters/<cluster ID>" \ -d '{"gke":{"targetServiceAccountEmail":"<your SA email>","castServiceAccountEmail":"<Cast SA email>"}}'
AKS: workload identity impersonation
A user-assigned managed identity in your subscription is trusted by a federated identity credential for Cast AI's impersonation service account. See AKS workload identity impersonation for background and the Terraform module alternative.
-
Get the Cast AI impersonation principal:
curl -s -H "Authorization: Bearer <API key>" -X POST \ "<API root URL>/v1/kubernetes/external-clusters/impersonation-service-account" \ -d '{"provider":"aks"}'Save the numeric
idfrom the response — it is used as the federated credential's subject (not theemail). -
Create the identity to impersonate:
az identity create \ --name <your identity name> \ --resource-group <resource group> \ --location <location> -
Create a federated credential on the identity, granting the Cast AI principal permission to impersonate it:
az identity federated-credential create \ --name <federated credential name> \ --identity-name <your identity name> \ --resource-group <resource group> \ --issuer "https://accounts.google.com" \ --subject "<Cast AI impersonation principal ID>" \ --audiences "api://AzureADTokenExchange"Save the credential's resource ID (the
idfield in the output). -
Create the Cast AI role and assign it to the identity, scoped to the cluster and node resource groups (see Cloud permissions).
WarningAssign the role at each resource group scope individually — assignments inherited from the subscription level are not accepted by credential validation. Use the custom role with the documented action list; built-in roles such as Contributor do not satisfy it.
-
Upload the federated credentials to Cast AI:
curl -s -H "Authorization: Bearer <API key>" -X POST \ "<API root URL>/v1/kubernetes/external-clusters/<cluster ID>" \ -d '{"aks":{},"credentials":"{\"subscriptionId\":\"<subscription ID>\",\"tenantId\":\"<tenant ID>\",\"clientId\":\"<identity client ID>\",\"federationId\":\"<federated credential resource ID>\"}"}'
Step 3: automatic reconciliation
Once the credentials validate, the cluster leaves read-only mode and becomes connected. Continue with node configurations and a node policy to enable Node Autoscaling.
Updated 2 days ago
