Skip to main content

Upgrade Runs

Upgrade Runs represent the execution of an Upgrade Plan. Each Upgrade Run references an Upgrade Plan and tracks the progress of upgrading resources according to the plan's rollout groups.

Upgrade Runs are cluster-scoped resources. They can be created by SKE when an Upgrade Plan's execution policy triggers, but they can also be created manually.

An Upgrade Run looks like this:

apiVersion: platform.syntasso.io/v1alpha1
kind: UpgradeRun
metadata:
name: redis-v1-to-v2-run-001
spec:
upgradePlanRef:
# Name of the UpgradePlan this run executes. Immutable after creation.
name: redis-v1-to-v2
# Set to true to pause execution. Defaults to false.
suspend: false

Upgrade Plan Reference

The upgradePlanRef field references the Upgrade Plan that this run executes. This field is immutable: once set, it cannot be changed.

spec:
upgradePlanRef:
name: redis-v1-to-v2

When the referenced Upgrade Plan exists, the Upgrade Run will resolve the plan and begin execution. If the plan does not exist, the Upgrade Run will set a PlanResolved condition with status False and reason PlanNotFound. A run that starts before its plan exists can still resolve later if the plan appears.

Suspending an Upgrade Run

You can pause an in-progress Upgrade Run by setting suspend to true:

spec:
suspend: true

Setting suspend back to false resumes execution. This allows you to temporarily halt an upgrade without deleting the run.

Previewing an upgrade before it runs

You can review exactly which resources an Upgrade Run will touch before any of them are upgraded by creating the run suspended:

apiVersion: platform.syntasso.io/v1alpha1
kind: UpgradeRun
metadata:
name: redis-v1-to-v2-preview
spec:
upgradePlanRef:
name: redis-v1-to-v2
suspend: true

A run created with suspend: true still takes its snapshot of eligible resources and writes the snapshot ConfigMap, but it does not patch any Resource Bindings. This gives you a stable, per-rollout-group list of what the run set out to change, without changing anything.

Once you are happy with the snapshot, set suspend back to false to let the run proceed. If you decide not to go ahead, delete the run; the snapshot ConfigMap is cleaned up with it.

Superseded runs

When an Upgrade Plan is on a schedule and the next trigger fires while a run is still Pending or InProgress, SKE does not start a second run alongside the first. It supersedes the active run instead:

  • The active run is patched with spec.suspend: true, so it stops starting new resource upgrades.
  • Its status.supersededBy is set to the name of the new run.
  • The new run starts in its place.

This keeps a single run rolling out at a time for a given plan, even when a schedule fires during a long-running upgrade.

How an UpgradeRun executes

When an UpgradeRun starts, it:

  1. Takes a snapshot of all Resource Bindings for the Promise that are on an eligible from version. The snapshot records each resource's version at the moment the run begins. This baseline is used throughout the run to detect drift.
  2. Waits for the target PromiseRevision to exist before the snapshot is finalised. If the target Promise Revision is not yet available, the run requeues until it appears.
  3. Processes rollout groups in plan order. For each group, it patches the spec.version on each matching Resource Binding to the target version and waits for Kratix to apply the upgrade. Only once every resource in the current group is accounted for does the run move to the next group.

Resource Outcomes

When a run processes a rollout group, each snapshotted resource is evaluated against its current live state. Because the run re-checks bindings on every reconcile cycle, resources can change between when the snapshot was taken and when their group is reached.

OutcomeWhen it applies
SucceededThe binding's lastAppliedVersion equals the target version; the upgrade was applied. This includes resources that were already applied at the target version by the time their group was reached.
SkippedThe binding no longer exists (resource was deleted), or the resource was upgraded to a different version externally.
FailedKratix reported an upgrade failure on the binding (UpgradeSucceeded=False) during the current run. The failure is part of the current run when the condition's lastTransitionTime is at or after the Upgrade Run's creationTimestamp. The entire run stops immediately.
PendingThe binding has been patched to the target version but Kratix has not yet applied it. If the binding is already at the target spec.version and the only upgrade failure was recorded before this Upgrade Run was created, the run treats that failure as the result of an earlier run. It sets kratix.io/manual-reconciliation: "true" on the Resource Binding to request a retry, then requeues and waits.

Skipped resources count towards group completion and do not block the run from advancing to the next group. A single failed resource stops the run entirely. Subsequent groups are not processed. Upgrade failures recorded before the Upgrade Run was created do not fail the current run.

Identifying a failed resource

The RunSucceeded condition and the rollout group status tell you how many resources failed and in which group, but not which specific resource. When a resource fails to upgrade, the run records a Kubernetes Event against the Upgrade Run naming the offending resource. Inspect the run's events to find it:

$ kubectl describe upgraderun redis-v1-to-v2-run-001
Name: redis-v1-to-v2-run-001
Namespace:
Labels: <none>
API Version: platform.syntasso.io/v1alpha1
Kind: UpgradeRun
Metadata:
Creation Timestamp: 2026-07-01T15:54:32Z
Finalizers:
platform.syntasso.io/upgraderun
Generation: 1
Owner References:
API Version: platform.syntasso.io/v1alpha1
Block Owner Deletion: true
Controller: true
Kind: UpgradePlan
Name: redis-v1-to-v2
UID: 98b582ba-e1e7-40bb-af7d-86ce0f31e18a
Resource Version: 10042
UID: c89f8ed6-7387-48c4-aad2-9db38b72444d
Spec:
Upgrade Plan Ref:
Name: redis-v1-to-v2
Status:
Completed Resources: 2
Conditions:
Last Transition Time: 2026-07-01T15:54:32Z
Message: UpgradePlan "redis-v1-to-v2" found
Reason: PlanFound
Status: True
Type: PlanResolved
Last Transition Time: 2026-07-01T15:54:33Z
Message: PromiseRevision for promise "redis" version "v2.0.0" is ready
Reason: PromiseRevisionReady
Status: True
Type: TargetRevisionReady
Last Transition Time: 2026-07-01T16:00:46Z
Message: 1 resource(s) failed to upgrade in rollout group "dev"
Reason: ResourceUpgradeFailed
Status: False
Type: RunSucceeded
Finished At: 2026-07-01T16:00:46Z
Resource List Refs:
Name: redis-v1-to-v2-run-001-resource-snapshot
Rollout Groups:
Failed: 1
Name: dev
Skipped: 0
Succeeded: 2
Total: 3
Failed: 0
Name: staging
Skipped: 0
Succeeded: 0
Total: 2
State: Failed
Total Resources: 5
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal GroupInProgress 9m21s (x2 over 9m21s) UpgradeRunController Group "dev": 0/3 resources upgraded to v2.0.0
Warning ResourceUpgradeFailed 3m28s UpgradeRunController Resource default/dev-r2 failed to upgrade to v2.0.0: upgrade gate denied
Normal GroupInProgress 3m28s (x2 over 3m28s) UpgradeRunController Group "dev": 1/3 resources upgraded to v2.0.0
Warning ResourceUpgradeFailed 3m28s UpgradeRunController Resource default/dev-r2 failed to upgrade to v2.0.0: upgrade gate denied
Normal GroupInProgress 3m23s (x2 over 3m23s) UpgradeRunController Group "dev": 1/3 resources upgraded to v2.0.0
Warning ResourceUpgradeFailed 3m7s UpgradeRunController Resource default/dev-r2 failed to upgrade to v2.0.0: upgrade gate denied
Warning UpgradeRunFailed 3m7s UpgradeRunController 2/5 resources upgraded to v2.0.0

The Events section at the end of the output identifies the resource that caused the group to fail.

Drift Detection

The snapshot records each resource's version at run start. If, by the time the run processes a resource, its version has been changed externally, the resource is Skipped rather than overwritten:

  • A resource upgraded to a version other than the target (e.g. v3.0.0 when the target is v2.0.0) is skipped.
  • A resource with lastAppliedVersion already at the target version is counted as Succeeded immediately; no patch is issued.
  • A resource with spec.version already at the target version, but with lastAppliedVersion still behind, remains Pending. If its only upgrade failure was recorded before the current run was created, the run adds the manual reconciliation label to the Resource Binding so Kratix retries the Resource Configure workflow.

PromiseRevision Gate

The run checks that the target Promise Revision exists at two points, with different behaviour each time:

Before the snapshot is taken: if the target PromiseRevision does not yet exist, the run requeues and waits. No failure is recorded. This handles the case where the revision is still being created when the run starts.

Once the snapshot exists and the rollout is underway: if the PromiseRevision is deleted, the run transitions immediately to Failed with reason PromiseRevisionNotFound. Resources that have not yet been patched remain on their current version.

Status

The Upgrade Run status tracks the progress of the upgrade across all rollout groups.

status:
# Overall execution state: (empty), Pending, InProgress, Completed, Failed, or Cancelled.
state: InProgress
# Total number of resources across all rollout groups.
totalResources: 10
# Resources successfully upgraded so far (sum of each group's succeeded; excludes skipped and failed).
completedResources: 3
# References to ConfigMaps containing the snapshot of resources to be upgraded.
resourceListRefs:
- name: redis-v1-to-v2-run-001-resource-snapshot
rolloutGroups:
- name: dev
# Total resources in this group.
total: 5
# Resources successfully upgraded.
succeeded: 3
# Resources that failed to upgrade.
failed: 1
# Resources that were skipped.
skipped: 1
- name: staging
total: 5
succeeded: 0
failed: 0
skipped: 0
conditions:
- type: PlanResolved
status: "True"
reason: PlanFound
- type: RunSucceeded
status: "False"
reason: ResourceUpgradeFailed
message: "1 resource(s) failed to upgrade in rollout group \"dev\""

State

The state field reflects the overall execution state of the run:

StateMeaning
(empty)Waiting for the referenced Upgrade Plan or the target PromiseRevision to be available
PendingRun is active but rollout has not started. Counts as active on the parent plan (phase: Running). The controller typically leaves this empty until the snapshot is created, then sets InProgress.
InProgressSnapshot created, rollout underway
CompletedAll rollout groups finished successfully
FailedA resource reported an upgrade failure, or the target PromiseRevision was deleted mid-run
CancelledThe run was deleted while still in progress

Once a run reaches Completed, Failed, or Cancelled it is terminal. It will not be reconciled further. The controller sets finishedAt at that point.

When a run becomes terminal, the controller records a summary on the parent Upgrade Plan in status.lastRun.

Resource Snapshot

When an Upgrade Run begins, it records a snapshot of every resource it will upgrade, grouped by rollout group, in a ConfigMap in the kratix-platform-system namespace. Because the snapshot is written at the start of the run and does not change as the upgrade proceeds, it gives you an auditable record of exactly which resources a run is upgrading. You can use it to review the scope of an upgrade before it proceeds (see Previewing an upgrade before it runs) and to confirm afterwards what was in scope. The Managing Promise Upgrades guide walks through this workflow.

The resourceListRefs field on the run's status lists the ConfigMaps that hold the snapshot. In practice this is a single ConfigMap. Read it from the kratix-platform-system namespace:

kubectl -n kratix-platform-system get configmap <snapshot-name> -o yaml

Each entry records the resource's namespace and name, the version captured at snapshot time (lastAppliedVersion), and its spec.version (specVersion). These versions also form the baseline used for drift detection.

{
"groups": [
{
"name": "dev",
"resources": [
{
"namespace": "team-a",
"name": "r1",
"lastAppliedVersion": "v1",
"specVersion": "v1"
}
]
}
]
}

Rollout Group Status

Each entry in groups summarises the upgrade progress of a single rollout group:

FieldDescription
nameName of the rollout group
totalTotal number of resources in this group
succeededNumber of resources successfully upgraded
failedNumber of resources that failed to upgrade
skippedNumber of resources that were skipped

Conditions

The Upgrade Run reports its state via standard Kubernetes conditions:

ConditionDescription
PlanResolvedTrue when the referenced Upgrade Plan exists; False with reason PlanNotFound when absent
RunSucceededTrue with reason RunCompleted when all rollout groups complete successfully; False with reason ResourceUpgradeFailed when a resource fails, PromiseRevisionNotFound when the target revision is deleted mid-run, or RunCancelled when the run is deleted in progress

Manually Creating an Upgrade Run

Upgrade Runs are typically created automatically by the system when an Upgrade Plan's execution policy triggers (via repeatSchedule or executeAt). You can also create one manually to trigger an immediate upgrade:

kubectl apply -f - <<EOF
apiVersion: platform.syntasso.io/v1alpha1
kind: UpgradeRun
metadata:
name: redis-v1-to-v2-manual-run
spec:
upgradePlanRef:
name: redis-v1-to-v2
EOF

Deleting an Upgrade Run

When an Upgrade Run that is still in progress is deleted, the controller marks it Cancelled, records the outcome on the parent Upgrade Plan's status.lastRun, and then removes the associated resource snapshot ConfigMap.

When a terminal run is deleted, the snapshot ConfigMap is cleaned up automatically. The plan's lastRun summary is not removed.