Deployment Priorities
Deployment priorities control the order in which PaletteAI applies a Workload's resources to a cluster. Components that share a deployment priority are applied together as a batch, and batches are applied sequentially in ascending priority order. During rollout, PaletteAI reports the progress of each batch in the workload status as a priority phase.
The term deployment priority appears in three related but distinct places. This page explains each one, how they interact during rollout, and how to inspect priority phase status when debugging.
| Usage | Field | Resource | Purpose |
|---|---|---|---|
| Component deployment priority | spec.workload.components[].deploymentPriority | WorkloadProfile (rendered as spec.components[].deploymentPriority on the Workload) | Assigns each component to a batch and controls the order in which batches are applied. |
| Output deployment priority | spec.workload.objectOutputRefs[].deploymentPriority | WorkloadProfile (rendered as spec.objectOutputRefs[].deploymentPriority on the Workload) | Controls when an object output is resolved during the rollout. |
| Priority phase status | status.priorityPhases (Workload) and status.statuses.<cluster-name>.priorityPhases (WorkloadDeployment) | Workload (spoke), WorkloadDeployment (hub) | Reports the current phase of each deployment priority during rollout. |
Traits do not have their own deployment priority. A trait is always rendered and applied together with the component it is attached to, in that component's batch.
Component Deployment Priority
The deploymentPriority field on each component assigns the component to a batch. The following rules apply:
-
A lower numeric value means the component is deployed earlier. The minimum value is
1. -
When
deploymentPriorityis not set, the component defaults to a deployment priority of1. -
All components with the same deployment priority form one batch and are applied concurrently.
-
The set of deployment priorities within a workload must be a contiguous sequence starting at
1, with no gaps between unique values. For example,3, 1, 2is valid, but1, 3(missing2) and2, 3, 4(missing1) are rejected by the validation webhook. -
The order in which components appear in the YAML does not matter, only their
deploymentPriorityvalues.
You can set a component's deployment priority in the UI with the Priority drawer action when creating a workload profile, or directly in YAML.
Batch Gating
Batches are not applied on a timer. PaletteAI applies deployment priority N + 1 only after deployment priority N reports ready, which requires all of the following:
-
Every component and trait in batch
Nreports healthy, according to its health policy. -
Every definition output declared by batch
Ncomponents and traits has been collected. -
Every object output assigned to deployment priority
Nhas been resolved.
Until these conditions are met, later batches remain rendered but are not yet dispatched, and the workload's priority phase status shows where the rollout is blocked. This gating is what makes deployment priorities useful for dependencies: a component in batch two can rely on resources, and reference macros that resolve outputs, from batch one.
The rollout proceeds through the batches as follows:
- PaletteAI renders all batches up front.
- PaletteAI applies the batch 1 resources and waits until every batch 1 component, trait, and output is ready. While it waits,
priorityPhases[0]reportsstartingorunhealthy. - Once batch 1 reports ready (
priorityPhases[0]: running), PaletteAI applies the batch 2 resources and repeats the same readiness check forpriorityPhases[1]. - After the final batch reports ready, PaletteAI resolves any outputs that do not declare a deployment priority.
Batch Order Example
The following workload profile deploys five components across three deployment priorities, and resolves two object outputs at different points in the rollout.
apiVersion: spectrocloud.com/v1beta1
kind: WorkloadProfile
metadata:
name: batching-example
spec:
workload:
objectOutputRefs:
- name: storageClassName
deploymentPriority: 1
pathRef:
apiVersion: storage.k8s.io/v1
kind: StorageClass
name: fast-ssd
path: .metadata.name
- name: apiEndpoint # no deploymentPriority; resolved after the final batch
pathRef:
apiVersion: v1
kind: Service
name: api-server
namespace: demo
path: .status.loadBalancer.ingress[0].ip
components:
- name: database
properties: ...
type: my-database # omitted deploymentPriority; defaults to 1
- name: cache
deploymentPriority: 1
properties: ...
type: my-cache
- name: api-server
deploymentPriority: 2
properties: ...
type: webservice
- name: frontend
deploymentPriority: 2
properties: ...
type: webservice
- name: smoke-test
deploymentPriority: 3
properties: ...
type: my-batch-job
PaletteAI applies the resulting workload in the following order.
| Step | Deployment Priority | What Happens |
|---|---|---|
| 1 | 1 | database and cache are applied concurrently. The storageClassName object output is resolved during this batch. |
| 2 | Gate | The rollout waits until database and cache are healthy and all priority 1 outputs are collected. Until then, priorities 2 and 3 are rendered but not applied. |
| 3 | 2 | api-server and frontend are applied concurrently. |
| 4 | Gate | The rollout waits until api-server and frontend are healthy. |
| 5 | 3 | smoke-test is applied. |
| 6 | After the final priority | The apiEndpoint object output, which has no deploymentPriority, is resolved during post-deploy. |
Output Deployment Priority
Object outputs accept an optional deploymentPriority field that controls when the output value is read during the rollout:
-
Set - The output is resolved during that batch. The value must be between
1and the highest deployment priority used by the workload's components. Use this when a later batch references the output through a macro, or when the source object only exists after an earlier batch is applied. -
Unset - The output is resolved during post-deploy, after the final deployment priority reports ready.
An object output that cannot be resolved blocks its batch from reporting ready, which in turn blocks all later batches. If the referenced object or path is not found during rendering, the workload is marked unhealthy and the rollout does not proceed.
Definition outputs do not have their own deploymentPriority field. They are always collected as part of the batch of the component or trait that produces them.
Priority Phase Status
While a workload rolls out, PaletteAI tracks two levels of phase information:
-
Workload phase (
status.phase) - The single overall phase of the workload or WorkloadDeployment. This is thePHASEcolumn shown bykubectl get workloadsandkubectl get workloaddeployments. -
Priority phases (
status.priorityPhases) - An array with one entry per deployment priority, in ascending priority order. Index0reports deployment priority1, index1reports deployment priority2, and so on.
The following table describes the phase values and where each can appear.
| Phase | Applies To | Meaning |
|---|---|---|
rendering | Workload phase, priority phases | The batch is being rendered, or it has been rendered and is waiting for the previous deployment priority to become ready before it is applied. |
starting | Workload phase only | Rendering succeeded and resources are being dispatched to the cluster. |
running | Workload phase, priority phases | All resources in the batch were applied, every component and trait is healthy, and all outputs for the batch were collected. The workload phase is running only when every deployment priority is ready. |
unhealthy | Workload phase, priority phases | Resources were applied, but one or more components or traits are not healthy, or expected outputs are missing. |
failed | Workload phase, priority phases | An error occurred while rendering, validating, or applying the batch, and the rollout cannot proceed. |
deleting | Workload phase, priority phases | The workload is being deleted. |
The workload status also records other information per deployment priority. In status.appliedResources and status.components, the outer array is indexed by deployment priority in the same way as status.priorityPhases.
In addition to phases, workloads record per-priority conditions in status.conditions. Condition types that apply to a specific deployment priority are suffixed with the priority number: Rendered-1, DryRun-1, Dispatched-1, Applied-1, Ready-1, and, when Flux is used for dispatch, FluxKustomizationReady-1. The Ready-<N> condition message is the most useful for debugging, as it lists the unhealthy components and missing outputs that are blocking the batch.
Workload and WorkloadDeployment Status
Where you inspect priority phases depends on which cluster you are connected to:
-
Spoke cluster - The
Workloadresource carriesstatus.priorityPhasesdirectly. -
Hub cluster - The
WorkloadDeploymentresource aggregates the status of each spoke workload understatus.statuses, keyed by cluster name. Each entry contains that cluster'spriorityPhases,phase, and per-prioritycomponentsstatuses. The WorkloadDeployment applies its own hub resources as a single unit, so its top-level status has aphasebut nopriorityPhasesarray; per-priority detail always comes from the aggregated spoke statuses.
Inspect Priority Phases During Rollout
To check how far a rollout has progressed on a spoke cluster (or on the hub when it deploys to itself), read the workload's priorityPhases.
kubectl get workload <workload-name> --namespace <namespace> \
--output jsonpath='{.status.priorityPhases}'
["running", "rendering", "rendering"]
In this example, deployment priority 1 is ready, and priorities 2 and 3 are rendered but waiting. If priority 1 were unhealthy instead, the rollout would be blocked there.
From the hub cluster, read the aggregated phases on the WorkloadDeployment for a specific spoke cluster.
kubectl get workloaddeployment <deployment-name> --namespace <project-namespace> \
--output jsonpath='{.status.statuses.<cluster-name>.priorityPhases}'
To find out why a deployment priority is not progressing, review the Ready-<N> condition for the blocked priority. Its message lists the unhealthy components, unhealthy traits, and missing outputs.
kubectl get workload <workload-name> --namespace <namespace> \
--output jsonpath='{.status.conditions[?(@.type=="Ready-1")].message}'
deployment priority 1 unhealthy:
- Component database unhealthy - 0 / 1 replicas ready
- Definition Output storageClassName missing for component database
You can also review the per-priority component statuses, which include the health flag and any custom status message reported by each component. The first index selects the deployment priority.
kubectl get workload <workload-name> --namespace <namespace> \
--output jsonpath='{.status.components[0]}' | jq
A later deployment priority that stays in rendering is usually not the problem itself. Work backwards to the first deployment priority that is not running, then inspect its Ready-<N> condition and component statuses to find the blocking component, trait, or output.