Skip to content
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
3e61e2e
feat(otel-container-insights): add ServiceMonitor/PodMonitor v2 OTLP …
wenegiemepraise Jun 19, 2026
b721ec3
feat(observability): support per-node Target Allocator allocation str…
wenegiemepraise Jun 26, 2026
0222e9f
Merge remote-tracking branch 'origin/main' into otel-ci-smpm-scrape-path
wenegiemepraise Jul 9, 2026
a51dc39
Merge branch 'otel-ci-smpm-scrape-path' into helm-per-node-allocation
wenegiemepraise Jul 9, 2026
072635b
feat(observability): bundle ServiceMonitor/PodMonitor CRDs for zero-s…
wenegiemepraise Jul 9, 2026
48e8330
docs(otel-ci): correct $$$1 escaping comment
wenegiemepraise Jul 20, 2026
32b6ae5
feat(observability): grant TA CRD watch RBAC under scraping gate
wenegiemepraise Jul 21, 2026
ee2df6e
fix(observability): restore unhyphenated operator feature-gate IDs
wenegiemepraise Jul 21, 2026
cd3fb5e
fix(observability): gate prometheuscr scope processor on SM/PM enable…
wenegiemepraise Jul 21, 2026
7911c6c
fix(observability): render TA ClusterRole/Binding once, not per agent
wenegiemepraise Jul 21, 2026
8bf3d4e
fix(observability): bump bundled SM/PM CRDs to prometheus-operator v0…
wenegiemepraise Jul 22, 2026
dee02ff
fix(observability): match release-namespace when adopting bundled CRDs
wenegiemepraise Jul 22, 2026
e753a60
test(observability): add shebang and anchor CRD matrix grep patterns
wenegiemepraise Jul 22, 2026
7dd2d8d
fix(observability): fail on invalid prometheusCRDs.install value
wenegiemepraise Jul 22, 2026
1a46b3f
Merge otel-ci-smpm-scrape-path (#329) into helm-crd-bundling
wenegiemepraise Jul 22, 2026
7bfede6
fix(observability): scope per-node allocationStrategy to the otelCI path
wenegiemepraise Jul 22, 2026
d57f318
docs(observability): clarify target_node is user-supplied, not chart …
wenegiemepraise Jul 22, 2026
d8a49d3
fix(observability): stop stamping node on the SM/PM scraping path
wenegiemepraise Jul 22, 2026
c626240
Merge otel-ci-smpm-scrape-path (#329) into helm-per-node-allocation
wenegiemepraise Jul 22, 2026
028a408
Merge helm-per-node-allocation (#330) into helm-crd-bundling
wenegiemepraise Jul 22, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6405,9 +6405,10 @@ spec:
allocationStrategy:
description: |-
AllocationStrategy determines which strategy the target allocator should use for allocation.
The current option is consistent-hashing.
The options are consistent-hashing and per-node.
enum:
- consistent-hashing
- per-node
type: string
enabled:
description: Enabled indicates whether to use a target allocation
Expand Down
33 changes: 33 additions & 0 deletions charts/amazon-cloudwatch-observability/templates/_helpers.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,25 @@ Expand the name of the chart.
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}

{{/*
Whether to bundle the community ServiceMonitor/PodMonitor CRDs. Honours
.Values.prometheusCRDs.install: "always" => true; "never" => empty;
"auto" (default) => true only when otelContainerInsights.enabled is true.
Returns the string "true" when CRDs should be rendered, empty otherwise.
*/}}
{{- define "amazon-cloudwatch-observability.prometheusCRDsEnabled" -}}
{{- $install := "auto" -}}

@musa-asad musa-asad Jul 21, 2026

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.

prometheusCRDsEnabled only matches always and never exactly, so anything else falls through and bundles the CRDs, meaning a typo like nevr silently bundles when otelCI is on. Could we add a fail branch for anything that isn't auto, always, or never, like the sibling key already does?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

split auto into its own branch and added a catch-all else that fails with prometheusCRDs.install must be one of "auto", "always", or "never", got: , matching the metricResolution sibling.

{{- if hasKey .Values "prometheusCRDs" -}}
{{- $install = (.Values.prometheusCRDs.install | default "auto") -}}
{{- end -}}
{{- if eq $install "always" -}}
true
{{- else if eq $install "never" -}}
{{- else if .Values.otelContainerInsights.enabled -}}
true
{{- end -}}
{{- end -}}

{{- define "amazon-cloudwatch-observability.common.tolerations" -}}
{{- $tolerations := .context.Values.tolerations }}
{{- if .component }}
Expand Down Expand Up @@ -191,6 +210,20 @@ Logic:
{{- end -}}
{{- end -}}

{{/*
Returns "true" when otelContainerInsights-driven ServiceMonitor/PodMonitor scraping
applies to the given agent. True when otelContainerInsights is enabled, the agent is
the configured targetAgent, and at least one of serviceMonitor/podMonitor is enabled.
Accepts a dict with "agentName" (string) and "context" (root context $).
*/}}
{{- define "cloudwatch-agent.otelCIScrapeEnabled" -}}
{{- $ctx := .context -}}
{{- $agentName := .agentName -}}
{{- if and $ctx.Values.otelContainerInsights.enabled (eq $agentName $ctx.Values.otelContainerInsights.targetAgent) (or $ctx.Values.otelContainerInsights.serviceMonitor.enabled $ctx.Values.otelContainerInsights.podMonitor.enabled) -}}
true
{{- end -}}
{{- end -}}

{{/*
Helper function to modify cloudwatch-agent config
*/}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,23 @@ receivers:
- targets:
- ${env:HOST_IP}:10250

{{- if or .Values.otelContainerInsights.serviceMonitor.enabled .Values.otelContainerInsights.podMonitor.enabled }}
# ServiceMonitor/PodMonitor scraping via the Target Allocator (prometheusCR discovery).
# The Target Allocator deployed for the targetAgent serves the scrape jobs derived from
# ServiceMonitor/PodMonitor CRs; this receiver pulls this collector's assigned shard and
# routes the series into the v2 OTLP pipeline (-> CloudWatch/Zeus). Requires the Target
# Allocator + prometheusCR to be enabled for the targetAgent and the POD_NAME env (set below).
prometheus/cw_k8s_ci_v0_prometheuscr:
target_allocator:
endpoint: https://{{ .Values.otelContainerInsights.targetAgent }}-target-allocator-service:80
interval: {{ .Values.otelContainerInsights.metricResolution }}
collector_id: ${env:POD_NAME}
tls:
ca_file: /etc/amazon-cloudwatch-observability-agent-cert/tls-ca.crt
cert_file: /etc/amazon-cloudwatch-observability-agent-ta-client-cert/client.crt
key_file: /etc/amazon-cloudwatch-observability-agent-ta-client-cert/client.key
{{- end }}

{{- if .Values.dcgmExporter.enabled }}
prometheus/cw_k8s_ci_v0_dcgm:
config:
Expand Down Expand Up @@ -329,6 +346,16 @@ processors:
- set(attributes["cloudwatch.solution"], "k8s-otel-container-insights")
- set(attributes["cloudwatch.pipeline"], "efa")

transform/cw_k8s_ci_v0_set_scope_prometheuscr:
error_mode: ignore
metric_statements:
- context: scope
statements:
- set(scope.schema_url, "")
- set(attributes["cloudwatch.source"], "cloudwatch-agent")
- set(attributes["cloudwatch.solution"], "k8s-otel-container-insights")
- set(attributes["cloudwatch.pipeline"], "prometheus-cr")

transform/cw_k8s_ci_v0_set_scope_ebs_csi:
error_mode: ignore
metric_statements:
Expand Down Expand Up @@ -829,6 +856,27 @@ service:
exporters:
- otlphttp/cw_k8s_ci_v0_metrics_dest

{{- if or .Values.otelContainerInsights.serviceMonitor.enabled .Values.otelContainerInsights.podMonitor.enabled }}
metrics/cw_k8s_ci_v0_prometheuscr:
receivers: [prometheus/cw_k8s_ci_v0_prometheuscr]
# Phase 1 base chain + node enrichment: set_node_name/promote_node_name stamp
# resource.attributes["k8s.node.name"] = the scraping agent's own node
# (${env:K8S_NODE_NAME}). Combined with the target_node label from the SM/PM
# relabeling, this lets per-node allocation be verified end-to-end (target_node
# must equal k8s.node.name). Also satisfies the roadmap's node-enrichment goal.
processors:
- filter/cw_k8s_ci_v0_scrape_metadata
- metricstarttime/cw_k8s_ci_v0
- transform/cw_k8s_ci_v0_set_cluster_name
- transform/cw_k8s_ci_v0_set_scope_prometheuscr
- transform/cw_k8s_ci_v0_set_node_name
- transform/cw_k8s_ci_v0_promote_node_name
- resourcedetection/cw_k8s_ci_v0
- batch/cw_k8s_ci_v0_metrics_dest
exporters:
- otlphttp/cw_k8s_ci_v0_metrics_dest
{{- end }}

{{- if .Values.dcgmExporter.enabled }}
metrics/cw_k8s_ci_v0_dcgm:
receivers: [prometheus/cw_k8s_ci_v0_dcgm]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,21 +110,46 @@ spec:
{{- else if ne (trimAll " \n\t" $generatedOtelConfig) "{}" }}
otelConfig: {{ include "cloudwatch-agent.modify-otel-config" (merge (dict "OtelConfig" $generatedOtelConfig) $) }}
{{- end }}
{{- $otelCIScrape := eq (include "cloudwatch-agent.otelCIScrapeEnabled" (dict "agentName" $agent.name "context" $)) "true" }}
{{- $taEnabled := or $agent.prometheus.targetAllocator.enabled $otelCIScrape }}
{{- if $agent.prometheus.config }}
prometheus:
{{- with $agent.prometheus.config }}
config:
{{- toYaml . | nindent 6 }}
{{- end }}
{{- else if $taEnabled }}
# The operator builds the Target Allocator config from spec.prometheus and requires
# a prometheus.config containing a scrape_configs key (see operator
# targetallocator/adapters GetPromConfig). With prometheusCR (ServiceMonitor/
# PodMonitor) discovery the static scrape list is empty -- the Target Allocator
# discovers targets from ServiceMonitor/PodMonitor CRs.
prometheus:
config:
scrape_configs: []
{{- end }}
{{- if $agent.prometheus.targetAllocator.enabled }}
{{- if $taEnabled }}
targetAllocator:
enabled: {{ $agent.prometheus.targetAllocator.enabled | default false }}
enabled: true
image: {{ template "target-allocator.image" (merge $agent.prometheus.targetAllocator.image (dict "region" $.Values.region)) }}
allocationStrategy: "consistent-hashing"
{{- if $agent.prometheus.targetAllocator.prometheusCR.enabled }}
allocationStrategy: {{ $agent.prometheus.targetAllocator.allocationStrategy | default "per-node" | quote }}
{{- if or $agent.prometheus.targetAllocator.prometheusCR.enabled $otelCIScrape }}
prometheusCR:
enabled: {{ $agent.prometheus.targetAllocator.prometheusCR.enabled | default false }}
enabled: true
{{- if $otelCIScrape }}
scrapeInterval: {{ $.Values.otelContainerInsights.metricResolution | quote }}
{{- if not $.Values.otelContainerInsights.serviceMonitor.enabled }}
# serviceMonitor.enabled=false: select a label no real ServiceMonitor carries,
# so the Target Allocator discovers no ServiceMonitors.
serviceMonitorSelector:
amazon-cloudwatch-observability.aws/otel-ci-scrape: disabled
{{- end }}
{{- if not $.Values.otelContainerInsights.podMonitor.enabled }}
# podMonitor.enabled=false: select a label no real PodMonitor carries.
podMonitorSelector:
amazon-cloudwatch-observability.aws/otel-ci-scrape: disabled
{{- end }}
{{- end }}
{{- end }}
{{- end }}
{{- with $agent.resources }}
Expand Down Expand Up @@ -281,6 +306,12 @@ spec:
{{- if $.Values.otelContainerInsights.enabled }}
- name: OTEL_CI_VERSION
value: "1.0.0"
# POD_NAME is used as the Target Allocator collector_id by the prometheusCR
# receiver (otel-container-insights.config) so each agent pulls its own shard.
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
{{- end }}
{{- with $agent.env }}
{{- . | toYaml | nindent 2 }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ spec:
- "--auto-instrumentation-dotnet-image={{ template "auto-instrumentation-dotnet.image" . }}"
- "--auto-instrumentation-nodejs-image={{ template "auto-instrumentation-nodejs.image" . }}"
- "--target-allocator-image={{ template "target-allocator.image" (merge .Values.agent.prometheus.targetAllocator.image (dict "region" $.Values.region)) }}"
- "--feature-gates=operator.autoinstrumentation.multiinstrumentation,operator.autoinstrumentation.multiinstrumentation.skipcontainervalidation"
- "--feature-gates=operator.autoinstrumentation.multi-instrumentation,operator.autoinstrumentation.multi-instrumentation.skip-container-validation"

@musa-asad musa-asad Jul 21, 2026

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.

Same --feature-gates issue as #329: hyphenated multi-instrumentation IDs the pinned operator doesn't register, so it CrashLoopBackOffs. Since it comes from #329, could we fix it there and rebase?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Will do

command:
- /manager
name: manager
Expand Down
Loading
Loading