Skip to content

feat: support custom labels on versioned Deployments - #639

Merged
jaypipes merged 3 commits into
temporalio:mainfrom
paulhobbel:feat/deployment-labels
Oct 20, 2026
Merged

jaypipes merged 3 commits into
temporalio:mainfrom
paulhobbel:feat/deployment-labels

Conversation

@paulhobbel

@paulhobbel paulhobbel commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

What was changed

Adds spec.deploymentLabels to WorkerDeployment. The controller copies these labels onto the metadata of each versioned Deployment it creates.

spec:
  deploymentLabels:
    team: payments
    example.com/instrumentation: "false"
  • Selector labels always win: they are merged last, and a CEL rule on the field rejects temporal.io/build-id and temporal.io/deployment-name.
  • Changes are applied in place to the Deployments of every version the controller manages (Target, Current and Draining), in the same write as the rolling-update strategy sync. No new Build ID is created and pods don't restart. The controller records the keys it applied in the temporal.io/managed-deployment-labels annotation, so removing a key from deploymentLabels removes it from the Deployments, while labels added by other tools are kept.
  • The validating webhook checks label keys and values, so an invalid label is rejected at admission instead of stalling the rollout.

Why?

Today the generated Deployment only carries temporal.io/build-id and temporal.io/deployment-name. Labels in the pod template reach the pods, but tools that act on the Deployment object itself never see them. The case we hit: an admission webhook that opts workloads out by a label on the Deployment. It couldn't see the opt-out, so it instrumented the versioned Deployments and rewrote their pod template.

I chose an explicit field over copying the WorkerDeployment's own metadata.labels. Those often carry GitOps tracking labels (e.g. Argo CD's app.kubernetes.io/instance) or kustomize commonLabels. Copying them would make controller-owned Deployments look like resources managed by the GitOps tool, which can then report them as out of sync or prune them.

Checklist

  1. Closes [Feature Request] Support custom labels on generated Kubernetes Deployment resources #187

  2. How was this tested:

    • Unit tests for ApplyDeploymentLabels: adding labels to existing Deployments, changing and removing keys, keeping labels from other tools, never touching selector labels, and no change when in sync.
    • Planner test: label changes are queued for existing Deployments, including one already queued by a connection change, and nothing is queued once in sync.
    • Webhook tests: invalid label keys and values are rejected.
    • Unit test for NewDeploymentWithOwnerRef: labels land on the Deployment, not on the pods or the selector, and selector keys win on conflict.
    • envtest CEL specs: custom labels are accepted, and both reserved keys are rejected.
    • make generate manifests, make test-unit and make lint-code pass locally.
  3. Any docs updates needed?
    Added a "Labels on versioned Deployments" section to docs/configuration.md.

🤖 Generated with Claude Code

@paulhobbel
paulhobbel requested review from a team, eniko-dif and jlegrone as code owners October 8, 2026 15:54
@CLAassistant

CLAassistant commented Oct 8, 2026 •

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@jaypipes jaypipes added this to the vNextNext milestone Oct 12, 2026

@jaypipes jaypipes left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like it. Thank you @paulhobbel! I'm targeting this for the v1.14.0 release (end of October), just FYI.

@jaypipes

Copy link
Copy Markdown
Collaborator

@paulhobbel You'll need to rebase to main in order to fix the failed e2e tests.

@tomba7 tomba7 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for putting this together, @paulhobbel!

Comment thread api/v1alpha1/workerdeployment_types.go
Comment thread internal/k8s/deployments.go
@paulhobbel

Copy link
Copy Markdown
Contributor Author

Hi all, will update this PR today

Add spec.deploymentLabels to WorkerDeployment. The labels are applied to the
metadata of each versioned Deployment the controller creates, so tools that
act on the Deployment object (admission webhooks that opt workloads in or out
by label, cost allocation) can see them. Controller-managed selector labels
always win, and a CEL rule rejects attempts to set them.

Closes temporalio#187
@paulhobbel
paulhobbel force-pushed the feat/deployment-labels branch from 6f802f6 to 3b7bcb4 Compare October 19, 2026 14:57
paulhobbel added a commit to paulhobbel/temporal-worker-controller that referenced this pull request Oct 19, 2026
Address review feedback on temporalio#639:

- The validating webhook now checks deploymentLabels keys and values with
  ValidateLabels. Before, an invalid value such as "foo bar" passed admission
  and the controller then failed to create the versioned Deployment.
- Label changes are applied in place to the Deployments of every version the
  controller manages, in the same write as the strategy sync, without
  restarting pods. The keys the controller applied are recorded in the
  temporal.io/managed-deployment-labels annotation, so a key removed from the
  spec is removed from the Deployments while labels added by other tools are
  kept.

Amp-Thread-ID: https://ampcode.com/threads/T-01a1548c-55d5-7376-87f5-86064575b53a
Co-authored-by: Paul Hobbel <paul@enapi.com>
@paulhobbel
paulhobbel requested a review from tomba7 October 19, 2026 15:08

@jaypipes jaypipes left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One small bug I think I've uncovered @paulhobbel but overall this is great, thank you so much for this PR!

Comment thread internal/planner/planner.go Outdated
paulhobbel added a commit to paulhobbel/temporal-worker-controller that referenced this pull request Oct 19, 2026
Address review feedback on temporalio#639:

- The validating webhook now checks deploymentLabels keys and values with
  ValidateLabels. Before, an invalid value such as "foo bar" passed admission
  and the controller then failed to create the versioned Deployment.
- Label changes are applied in place to the Deployments of every version the
  controller manages, in the same write as the strategy sync, without
  restarting pods. The keys the controller applied are recorded in the
  temporal.io/managed-deployment-labels annotation, so a key removed from the
  spec is removed from the Deployments while labels added by other tools are
  kept.
@paulhobbel
paulhobbel force-pushed the feat/deployment-labels branch from f942c28 to cc3e43c Compare October 19, 2026 18:17
paulhobbel added a commit to paulhobbel/temporal-worker-controller that referenced this pull request Oct 19, 2026
Address review feedback on temporalio#639:

- The validating webhook now checks deploymentLabels keys and values with
  ValidateLabels. Before, an invalid value such as "foo bar" passed admission
  and the controller then failed to create the versioned Deployment.
- Label changes are applied in place to the Deployments of every version the
  controller manages, in the same write as the strategy sync, without
  restarting pods. The keys the controller applied are recorded in the
  temporal.io/managed-deployment-labels annotation, so a key removed from the
  spec is removed from the Deployments while labels added by other tools are
  kept.
@paulhobbel
paulhobbel force-pushed the feat/deployment-labels branch from cc3e43c to c34260f Compare October 19, 2026 18:21
Address review feedback on temporalio#639:

- The validating webhook now checks deploymentLabels keys and values with
  ValidateLabels. Before, an invalid value such as "foo bar" passed admission
  and the controller then failed to create the versioned Deployment.
- Label changes are applied in place to the Deployments of every version the
  controller manages, in the same write as the strategy sync, without
  restarting pods. The keys the controller applied are recorded in the
  temporal.io/managed-deployment-labels annotation, so a key removed from the
  spec is removed from the Deployments while labels added by other tools are
  kept.
@paulhobbel
paulhobbel force-pushed the feat/deployment-labels branch from c34260f to b92ea9f Compare October 19, 2026 18:27

@jaypipes jaypipes left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great stuff @paulhobbel thank you!

@jaypipes
jaypipes enabled auto-merge (squash) October 20, 2026 06:40
@paulhobbel

Copy link
Copy Markdown
Contributor Author

Hi @jaypipes it looks like I still need to accept the license. However, I already did and if I try to accept again it gives me an error

@jaypipes

Copy link
Copy Markdown
Collaborator

Hi @jaypipes it looks like I still need to accept the license. However, I already did and if I try to accept again it gives me an error

Nah, it's just a flaky issue with the CLA assistant thing :) I'll update the branch to main HEAD which should (hopefully) kick the CLA job into action...

@jaypipes
jaypipes merged commit 68e8bba into temporalio:main Oct 20, 2026
23 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature Request] Support custom labels on generated Kubernetes Deployment resources

4 participants