Skip to content

fix(collector): roll pods when Prometheus config changes#387

Closed
musa-asad wants to merge 1 commit into
aws:mainfrom
musa-asad:prometheus-config-pod-restart
Closed

fix(collector): roll pods when Prometheus config changes#387
musa-asad wants to merge 1 commit into
aws:mainfrom
musa-asad:prometheus-config-pod-restart

Conversation

@musa-asad

Copy link
Copy Markdown
Contributor

Summary

Roll agent pods when the Prometheus scrape config changes.

The pod-template restart-trigger sha256 was computed from instance.Spec.Config
only. A change to instance.Spec.Prometheus is rendered into a separate
ConfigMap, so the pod template stayed byte-identical and the workload controller
never rolled the pods. As a result, editing only the Prometheus scrape config did
not take effect until the pods were restarted by some other means — whereas an
agent-config (Spec.Config) change correctly rolls them.

This fixes that asymmetry so a Prometheus-only change triggers a rolling restart,
matching agent-config behavior, while leaving non-Prometheus agents unaffected.

Changes

internal/manifests/collector/annotations.go:

  • Annotations() (line ~31): hash input changed from
    getConfigMapSHA(instance.Spec.Config)getConfigMapSHA(configHashInput(instance)).
  • PodAnnotations() (line ~54, the map applied to the pod template): same change.
  • New configHashInput() helper (lines ~58–72): returns instance.Spec.Config, and
    when !instance.Spec.Prometheus.IsEmpty() appends the serialized
    instance.Spec.Prometheus.Yaml() (the existing PrometheusConfig.Yaml() serializer).
func configHashInput(instance v1alpha1.AmazonCloudWatchAgent) string {
	config := instance.Spec.Config
	if !instance.Spec.Prometheus.IsEmpty() {
		if promYaml, err := instance.Spec.Prometheus.Yaml(); err == nil {
			config += promYaml
		}
	}
	return config
}

The IsEmpty() guard keeps the hash input byte-identical to the agent config alone
for non-Prometheus agents, so they are unaffected: with no Prometheus config the hash
is still sha256(Spec.Config) (sha256("test") = 9f86d081…, unchanged). The
pre-existing TestDefaultAnnotations / TestUserAnnotations (which assert that same
9f86d081… value) continue to pass.

RELEASE_NOTES: added a Bug Fixes entry noting Prometheus-config changes now trigger a
rolling restart.

Test Output

Scenario reference — Test 2 (Prometheus-config tweak must roll pods)

From a DaemonSet doing Prometheus scraping, a small tweak to the Prometheus scrape
config (e.g. changing a relabel replacement value) must cause the agent pods to roll
so the new config takes effect. The configuration-values for this scenario:

agent:
  config:
    {
      "logs": { "metrics_collected": { "prometheus": {
        "log_group_name": "prometheus_test",
        "emf_processor": {
          "metric_namespace": "PrometheusTest",
          "metric_declaration": [
            { "source_labels": ["label1"], "label_matcher": "^value1$",
              "dimensions": [["datapoint_id"], ["datapoint_id","foo_0"]],
              "metric_selectors": ["^test_*"] }
          ]
        }
      } } }
    }
  prometheus:
    config:
      scrape_configs:
        - job_name: 'prometheus-sample-app'
          kubernetes_sd_configs:
            - role: pod
          relabel_configs:
            - source_labels: [__meta_kubernetes_pod_label_app]
              regex: prometheus-sample-app
              action: keep
            - target_label: label1
              replacement: value1
            - target_label: bug2probe       # benign relabel probe
              replacement: value3            # the "small tweak": value2 -> value3

Before / after (live test EKS cluster, no-TA DaemonSet)

A Prometheus-only change (value2 → value3) on the fixed operator image:

                         BEFORE (value2)             AFTER (value3)
prom-cm sha256   54f854b7...265971af7        a30400e3...77bd40f9d   CHANGED
value2 / value3  value2=1 value3=0           value2=0 value3=1      CHANGED
generation       64                          65                     BUMPED
podTemplateSha   b8fdb19a...565a1466c        211cc51e...0a06a6a0    CHANGED
pod uids         740c2e61 3e2c4dbc 60595d4a  0c3601a9 c1707fe3 8fa2350f   ALL NEW (rolled)

BEFORE the fix, the same Prometheus-only tweak changed the Prometheus ConfigMap hash
but left podTemplateSha and the pod uids unchanged (no restart). AFTER the fix the
Prometheus ConfigMap hash changes and the pod-template hash changes and the pods
roll (all-new uids, generation bump).

No regression — a subsequent agent-config change (agent.debug=true) still rolls the
pods (generation 65→66, podTemplateSha changes, all-new uids), exactly as before.

Unit tests

$ go test ./internal/manifests/collector/ -run 'PrometheusConfigChangeBumpsHash|EmptyPrometheusHashUnchanged|DefaultAnnotations|UserAnnotations' -v
=== RUN   TestDefaultAnnotations
--- PASS: TestDefaultAnnotations (0.00s)
=== RUN   TestUserAnnotations
--- PASS: TestUserAnnotations (0.00s)
=== RUN   TestPrometheusConfigChangeBumpsHash
--- PASS: TestPrometheusConfigChangeBumpsHash (0.00s)
=== RUN   TestEmptyPrometheusHashUnchanged
--- PASS: TestEmptyPrometheusHashUnchanged (0.00s)
PASS
ok  github.com/aws/amazon-cloudwatch-agent-operator/internal/manifests/collector  0.028s

$ go build ./...
(build OK)
  • TestPrometheusConfigChangeBumpsHash — hash is stable when nothing changes and
    changes when only Spec.Prometheus changes.
  • TestEmptyPrometheusHashUnchanged — with no Prometheus config the hash is
    byte-identical to sha256(Spec.Config) (9f86d081…), proving non-Prometheus agents
    are unaffected.

Test pass matrix (full Prometheus-on-EKS scenario suite)

Test Scenario Result
Test 1 DaemonSet, Prometheus scraping, Target Allocator disabled (baseline) PASS
Test 2 Small Prometheus-config tweak → pods must roll (this PR) PASS
Test 3 Single Deployment (1 replica), no Target Allocator → no spurious TA warning PASS
Test 4 StatefulSet, 2 replicas, Target Allocator disabled (baseline) PASS
Test 5 StatefulSet, 2 replicas, Target Allocator enabled → agent must not crash PASS

The pod-template restart-trigger sha256 was computed from Spec.Config only,
so a change to Spec.Prometheus (rendered into a separate ConfigMap) left the
pod template byte-identical and the workload controller did not roll the pods.

Fold the serialized Spec.Prometheus (PrometheusConfig.Yaml()) into the hash
input when it is non-empty, so a Prometheus-only change bumps the pod-template
annotation and triggers a rolling restart, matching agent-config behavior.
When no Prometheus config is set the hash input is byte-identical to the agent
config alone, leaving non-Prometheus agents unaffected.
@musa-asad

Copy link
Copy Markdown
Contributor Author

Merged into PR #386 — single PR for all operator target allocator fixes.

@musa-asad musa-asad closed this Jun 16, 2026
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.

1 participant