Skip to content

fix(helm)!: configure the OTel SDK via verbatim extraEnv, not chart keys#645

Merged
jensholdgaard merged 2 commits into
mainfrom
fix/helm-otel-extraenv-only
Jul 26, 2026
Merged

fix(helm)!: configure the OTel SDK via verbatim extraEnv, not chart keys#645
jensholdgaard merged 2 commits into
mainfrom
fix/helm-otel-extraenv-only

Conversation

@jensholdgaard

@jensholdgaard jensholdgaard commented Jul 26, 2026

Copy link
Copy Markdown
Owner

Why

Reverts most of #644's values surface the same day it landed, on a maintainer call about ownership:

OTel is very opinionated and people expect that these are configured this way, whereas S3 is a hard dep which should be explicit.

The per-signal keys (otel.traces.sampler, otel.metrics.exportInterval, …) re-modeled the OTel SDK's env-var vocabulary as chart values — a naming contract the chart doesn't own. The evidence that the coupling had real cost is #644's own review history: both bugs found there (the --reuse-values nil-pointer, the numeric-zero samplerArg drop) existed only because the chart interpreted those values. A verbatim passthrough cannot have either bug class.

This is also the chart-level mirror of RFC 0038 slice 4, which removed bespoke telemetry config from the binary in favour of the universal OTEL_* variables.

The ownership line

Surface Treatment Why
otel.exporterEndpoint stays a modeled value deployment topology — where this release sends telemetry — is the chart's to own
SDK behaviour (samplers, intervals, per-signal disable, resource attrs) verbatim extraEnv OTel's contract; its users already know it
S3 storage/credentials stays explicit values, untouched Ourios's own hard dependency

What

  • Global extraEnv (pre-existing) documented as the OTel surface, with the spec-defined variables listed in a comment block + links to the two authoritative pages (general SDK, OTLP exporter) — the list itself was checked against the OTel docs, not written from memory.
  • Per-role receiver/querier/compactor.extraEnv (new), appended after the global list. Kubernetes resolves a duplicate env name to the last entry, so two roles can carry different values for the same variable — the motivating case is per-role OTEL_RESOURCE_ATTRIBUTES.
  • ourios.commonEnv → role-aware ourios.workloadEnv. The s3CredentialsEnvFrom helper is byte-identical to main, and a render assertion pins that the s3 envFrom is unaffected by role env being set.

Breaking change

otel.traces/metrics/logs values are removed. Marked ! for honesty, though the blast radius is nil in practice: the keys merged to main earlier today and chart.yml (dispatch-only) never published them; no chart release ever carried them.

Verification

deploy/helm/render-tests.sh rewritten for the new contract — 10 assertions: defaults render no OTEL_*, endpoint renders, --reuse-values shape safety, global passthrough verbatim, role scoping both directions, the duplicate-key ordering on all three roles, and the s3 envFrom no-touch. All green locally + helm lint clean. (deploy-test.yml remains nightly/dispatch, not per-PR.)

Invariants

Chart-only. No CLAUDE.md §3 invariant or §4 hazard touched; §6.3 self-observability is served with a smaller owned surface.

Summary by CodeRabbit

  • New Features

    • Added global and per-role environment variable injection for receiver, querier, and compactor workloads.
    • Added support for configuring OpenTelemetry SDK behavior through standard OTEL_* environment variables.
    • Role-specific environment settings override duplicate global entries.
  • Documentation

    • Updated Helm values and telemetry guidance with configuration examples and OpenTelemetry references.
  • Breaking Changes

    • Removed chart-specific OpenTelemetry trace, metric, and log settings; use extraEnv instead.

Reverts #644's per-signal values surface (otel.traces/metrics/logs) the
same day it landed, before any chart publish carried it. The maintainer
call: OTel is opinionated and its users already know its env-var
contract — the chart wrapping OTEL_TRACES_SAMPLER and friends in
chart-specific keys couples us to a naming vocabulary we don't own.
Both review-found bugs in #644 (the --reuse-values nil-pointer and the
numeric-zero samplerArg drop) existed only because of that re-modeling;
a verbatim passthrough cannot have either bug class. This is the chart-
level mirror of RFC 0038 slice 4, which removed bespoke telemetry
config from the binary in favour of the universal OTEL_* variables.

The one OTel knob that stays modeled is otel.exporterEndpoint:
deployment topology (where this release sends its telemetry) is the
chart's to own; SDK behaviour is not. S3 config stays explicit values
for the inverse reason — a hard dependency whose contract is ours.

What replaces the keys:

- global extraEnv (existed) documented as the OTel surface, with the
  spec-defined variables listed in a comment block + links to the
  authoritative pages (sdk-environment-variables, protocol/exporter)
- per-role receiver/querier/compactor.extraEnv (new), appended after
  the global list — Kubernetes resolves a duplicate name to the last
  entry, so two roles can carry different values for the same variable
  (e.g. per-role OTEL_RESOURCE_ATTRIBUTES), pinned by render tests
- ourios.commonEnv becomes role-aware ourios.workloadEnv; the s3
  credentials envFrom path is untouched (asserted by a render test)

BREAKING CHANGE: the otel.traces/otel.metrics/otel.logs values from
#644 are removed (never published in a chart release; merged to main
earlier the same day). Set the corresponding OTEL_* variables in
extraEnv instead.

Signed-off-by: Jens Holdgaard Pedersen <Jens@holdgaard.org>
@jensholdgaard
jensholdgaard requested a review from Copilot July 26, 2026 16:54
@coderabbitai

coderabbitai Bot commented Jul 26, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@jensholdgaard, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 52 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 3ae1e28f-9d93-483d-9962-68480aa6ccbc

📥 Commits

Reviewing files that changed from the base of the PR and between 11493ae and e349cf0.

📒 Files selected for processing (1)
  • deploy/helm/ourios/templates/_helpers.tpl
📝 Walkthrough

Walkthrough

The Helm chart now models only the OTLP exporter endpoint and passes other OpenTelemetry settings through global or role-specific extraEnv. Workload templates use a role-scoped environment helper, with render tests covering ordering, scoping, endpoint handling, and secret sources.

Changes

OpenTelemetry environment passthrough

Layer / File(s) Summary
Telemetry values and documentation contract
deploy/helm/ourios/values.yaml, deploy/helm/ourios/README.md
Role-specific extraEnv arrays and precedence rules are documented; per-signal telemetry values are removed, leaving otel.exporterEndpoint as the modeled setting.
Role-scoped workload environment rendering
deploy/helm/ourios/templates/_helpers.tpl, deploy/helm/ourios/templates/*deployment.yaml, deploy/helm/ourios/templates/receiver-statefulset.yaml
ourios.workloadEnv renders the endpoint, global variables, and role variables in order for receiver, querier, and compactor workloads.
Rendered environment regression coverage
deploy/helm/render-tests.sh
Tests validate workload-scoped extraction, passthrough, role overrides, endpoint handling, nil telemetry values, and unchanged S3 envFrom behavior.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant HelmValues
  participant workloadEnv
  participant Workload
  HelmValues->>workloadEnv: provide endpoint and extraEnv values
  workloadEnv->>workloadEnv: append global extraEnv then role extraEnv
  workloadEnv->>Workload: render ordered env entries
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: moving OTel SDK config to verbatim extraEnv instead of chart keys.
Description check ✅ Passed The description covers the why, what, breaking change, and verification, but it omits the template's explicit Summary, Related, and Checklist sections.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/helm-otel-extraenv-only

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR reverts the Helm chart’s modeled OpenTelemetry SDK configuration surface (per-signal otel.* keys) in favor of passing OTel’s standard OTEL_* environment variables through verbatim via extraEnv, while keeping otel.exporterEndpoint as the single modeled telemetry value owned by the chart. It also introduces per-role extraEnv (receiver/querier/compactor) so role-specific overrides can be applied via Kubernetes’ “last env entry wins” behavior.

Changes:

  • Remove per-signal OTel chart values and document/configure OTel SDK behavior via global + per-role extraEnv.
  • Replace ourios.commonEnv with role-aware ourios.workloadEnv and wire it into all three workloads.
  • Rewrite Helm render assertions to validate the new env passthrough/override contract and guard upgrade/reuse-values shapes.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
deploy/helm/render-tests.sh Reworks render assertions to validate verbatim extraEnv passthrough, per-role scoping, and duplicate-key ordering.
deploy/helm/ourios/values.yaml Removes per-signal otel.* keys; documents OTel SDK env var contract and adds per-role extraEnv.
deploy/helm/ourios/templates/receiver-statefulset.yaml Switches env rendering to ourios.workloadEnv for the receiver role.
deploy/helm/ourios/templates/querier-deployment.yaml Switches env rendering to ourios.workloadEnv for the querier role.
deploy/helm/ourios/templates/compactor-deployment.yaml Switches env rendering to ourios.workloadEnv for the compactor role.
deploy/helm/ourios/templates/_helpers.tpl Implements ourios.workloadEnv and appends role-specific extraEnv after global extraEnv.
deploy/helm/ourios/README.md Updates “Self-telemetry” docs and values table to reflect extraEnv-based OTel configuration and role overrides.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread deploy/helm/render-tests.sh
Review of the diff showed the S3-adjacent lines (AWS_DEFAULT_REGION and
its region guard) changing for no functional reason: switching the
helper's calling convention to (dict "root" "role") forced a mechanical
.Values -> $root.Values rewrite of every line inside it. That is noise
in a PR whose contract is "S3 mechanics untouched".

Restore ourios.commonEnv to root-context — its S3 lines are now
byte-identical to main — and layer the role extraEnv in a thin
ourios.workloadEnv wrapper that includes it. Render output is unchanged
(the 10 assertions pass before and after).

Signed-off-by: Jens Holdgaard Pedersen <Jens@holdgaard.org>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.

@jensholdgaard
jensholdgaard merged commit bb54780 into main Jul 26, 2026
28 checks passed
@jensholdgaard
jensholdgaard deleted the fix/helm-otel-extraenv-only branch July 26, 2026 17:08
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