Skip to content

fix(k8s): stop hardcoding the CloudWatch logging annotations - #224

Merged
andres-nullplatform merged 1 commit into
mainfrom
feat/configurable-cloudwatch-annotations
Aug 13, 2026
Merged

fix(k8s): stop hardcoding the CloudWatch logging annotations#224
andres-nullplatform merged 1 commit into
mainfrom
feat/configurable-cloudwatch-annotations

Conversation

@andres-nullplatform

Copy link
Copy Markdown
Contributor

Closes #223.

Why

Five annotations were literals in both deployment templates:

nullplatform.logs.cloudwatch: 'true'
nullplatform.logs.cloudwatch.log_group_name: {{ .namespace.slug }}.{{ .application.slug }}
nullplatform.logs.cloudwatch.log_stream_log_retention_days: '7'
nullplatform.logs.cloudwatch.log_stream_name_pattern: >-
  type=${type};application=...;instance=${instance};container=${container}
nullplatform.logs.cloudwatch.region: {{ .region }}

So every pod in every account shipped to CloudWatch, under <namespace>.<application>, kept for exactly 7 days. None of it could change without a change to this repository — and the gate in particular decided routing for workloads whose account may not even use CloudWatch.

What

All five are removed. annotations: and the k8s_modifiers merges stay, so the same keys arrive from wherever an account's logging setup is owned.

They are removed rather than made configurable here on purpose. All five are inputs to the same consumer, the logs controller, and an override already stamps annotations through k8s_modifiers.deployment.annotations. Splitting them across two layers would mean two sources for one decision, and the two could then disagree — a gate pointing at one annotation family while the naming points at another produces logs that ship to the wrong place, or nowhere, with no error anywhere.

Keeping them in one place also makes the failure direction the safe one: a pod that nothing annotates ships nowhere.

Also fixes the scheduled_task region

scheduled_task/deployment/templates/deployment.yaml.tpl hardcoded region: us-east-1 instead of deriving it from the context like the k8s template did. Every scheduled task outside us-east-1 was naming the wrong CloudWatch region. Removing the block drops that too.

⚠️ Breaking for clusters with no override

A cluster that relied on these templates to stamp nullplatform.logs.cloudwatch: 'true' stops shipping application logs once its scopes are redeployed, until something injects the gate. The logs controller's rules are keyed on that annotation; an unannotated pod matches nothing and its records are dropped with no error.

Accounts that stamp their own gates through an override are unaffected. If a gradual path is wanted, the place for it is that override defaulting to CloudWatch when it finds no logging provider, rather than reinstating a literal here.

Verification

  • bats k8s/deployment/tests/*.bats scheduled_task/deployment/tests/*.bats314 passing, 0 failing.
  • Rendered both templates with no annotations at all: still a valid Deployment / CronJob with every container intact. annotations: renders as null, which the API server treats as absent.
  • Rendered with k8s_modifiers.deployment.annotations carrying the gate and the naming keys: they come through unchanged, at the right indentation, in both templates.
  • End-to-end against the override that will supply them (setup_logs_provider): the pod ends up with the four nullplatform.logs.cloudwatch.* values identical to what these templates used to produce, plus the gates the override resolves.

Closes #223.

Five annotations were literals in both deployment templates: the CloudWatch gate plus
the log group, retention, stream name pattern and region. Every pod in every account
therefore shipped to CloudWatch, under `<namespace>.<application>`, kept for exactly 7
days — and none of it could change without editing this repository.

They are removed rather than made configurable here. All five are the logs controller's
inputs, and whoever owns an account's logging setup already stamps annotations through
k8s_modifiers.deployment.annotations; splitting them across two layers would mean two
sources for one decision. Keeping them in one place is also what allows the gate and
the naming to disagree in only one direction: a pod that nothing annotates ships
nowhere, which is the right outcome for an account with no logging provider.

The templates still render `annotations:` and the modifier merges, so an override
supplies the same keys with the same values it used to get from here — verified against
a real render.

Also drops a bug: scheduled_task hardcoded `region: us-east-1` rather than deriving it
from the context like the k8s template did, so every scheduled task outside that region
named the wrong CloudWatch region.

BREAKING: a cluster relying on these templates to stamp
`nullplatform.logs.cloudwatch: 'true'` stops shipping application logs until an
override injects the gate.
@andres-nullplatform
andres-nullplatform force-pushed the feat/configurable-cloudwatch-annotations branch from 4f290f4 to 07dee78 Compare August 13, 2026 21:27
@andres-nullplatform
andres-nullplatform merged commit f8b08cf into main Aug 13, 2026
3 checks passed
@andres-nullplatform
andres-nullplatform deleted the feat/configurable-cloudwatch-annotations branch August 13, 2026 21:31
@andres-nullplatform
andres-nullplatform restored the feat/configurable-cloudwatch-annotations branch August 13, 2026 21:37
@andres-nullplatform
andres-nullplatform deleted the feat/configurable-cloudwatch-annotations branch August 13, 2026 21:41
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.

2 participants