Skip to main content
Version: v1.1.x

Delete Tenants

Delete a Tenant when the organization or division it represents is no longer needed. Tenant deletion is permanent and removes the Tenant from the PaletteAI hub cluster.

warning

PaletteAI prevents you from deleting a Tenant that has child Projects or active Tenant-scoped workloads. You must delete all Projects under the Tenant and all active Tenant-scoped ComputePools and AIWorkloads before you can delete the Tenant. Resources already terminating do not block deletion.

Limitations

  • Tenant deletion is not available in the PaletteAI user interface at this time. Tenants must be deleted using Kubernetes manifests and kubectl commands as described in this guide.

Prerequisites

  • kubectl installed and available in your $PATH.

  • The KUBECONFIG environment variable set to the path of the PaletteAI hub cluster's kubeconfig file.

    export KUBECONFIG=<kubeconfig-location>
  • A user with cluster-scoped permission to delete Tenant resources. The default PaletteAI Tenant admin ClusterRole does not grant delete on Tenant. A cluster administrator must perform the deletion or grant explicit delete permission on tenants.spectrocloud.com.

  • All child Projects under the Tenant deleted. Refer to Delete Projects for the Project deletion workflow.

  • No active Tenant-scoped ComputePools or AIWorkloads remain. Tenant-scoped workloads are created directly in the Tenant scope (not within Projects) and exist in the tenant-<tenant-name> namespace. Only active resources (those without a deletionTimestamp) block Tenant deletion; workloads already terminating do not require further cleanup.

Enablement

  1. Verify the Tenant has no child Projects.

    kubectl get tenant <tenant-name> --output jsonpath='{.status.childProjectCount}'

    The output must be 0. If the value is greater than zero, list the remaining Projects with the following command, then delete them before you continue. For the full workflow, refer to Delete Projects.

    kubectl get projects --all-namespaces --selector palette.ai/tenant-name=<tenant-name>
  2. Verify the Tenant has no active Tenant-scoped ComputePools or AIWorkloads.

    kubectl get computepools,aiworkloads --namespace tenant-<tenant-name>

    Only active resources block Tenant deletion. Resources already terminating (those with a deletionTimestamp set) may still appear in this list but do not require further cleanup. If any active ComputePools or AIWorkloads exist, delete them before you continue.

    kubectl delete computepool <computepool-name> --namespace tenant-<tenant-name>
    kubectl delete aiworkload <aiworkload-name> --namespace tenant-<tenant-name>
  3. Delete the Tenant.

    kubectl delete tenant <tenant-name>
    Example command
    kubectl delete tenant primary-dev
  4. (Optional) Delete the Tenant namespace.

    PaletteAI does not automatically delete the tenant-<tenant-name> namespace when you delete the Tenant. Before deleting it, confirm that no remaining Projects reference Settings resources in that namespace and that you no longer need any Secrets or Settings stored there.

    List the Settings in the Tenant namespace before deletion.

    kubectl get settings --namespace tenant-<tenant-name>
    warning

    Deleting the Tenant namespace permanently deletes all Settings resources and integration Secrets it contains. Settings deletion automatically removes their referenced Secrets. Ensure you no longer need those credentials before proceeding.

    kubectl delete namespace tenant-<tenant-name>
    Example command
    kubectl delete namespace tenant-primary-dev

Validate

Verify the Tenant no longer exists.

kubectl get tenants
Example Output
NAME      DISPLAYNAME      READY   SETTINGS   NAMESPACE   PROJECTS   AGE
default Default Tenant true default default 1 21d

Troubleshoot Tenant Deletion

If the Tenant delete request fails because child Projects remain, refer to Cannot Delete Tenant.

If the Tenant accepts the delete request but remains in a deleting state because active Tenant-scoped workloads still exist, check the GarbageCollected condition:

kubectl get tenant <tenant-name> --output json | jq '.status.conditions[] | select(.type == "GarbageCollected")'

When garbage collection is blocked, this condition reports status: "False" and reason: "GarbageCollectionBlocked". The message lists the remaining active ComputePools and AIWorkloads, for example:

cannot garbage-collect Tenant: 1 ComputePool(s) and 2 AIWorkload(s) still exist in namespace "tenant-<tenant-name>"; delete them first

List and delete the remaining active ComputePools and AIWorkloads in the tenant-<tenant-name> namespace as described in step 2 of Enablement. Resources already terminating do not block deletion; once only terminating workloads remain, the controller removes the finalizer automatically.