feat(helm): Support externally-managed HPAs via controller.autoscaling.horizontal.externalHPA#6311
Conversation
6ed9fca to
8efc6a6
Compare
Please create another pr for this and add a changelog entry for this specific fix |
8efc6a6 to
181430b
Compare
Done — split out to #6312 with its own CHANGELOG entry. Rebased this PR to drop the configmap commit. |
### Brief description of Pull Request Split off from #6311 per [@kalleep's request](#6311 (comment)). Fixes `templates/configmap.yaml` ignoring `alloy.configMap.key`. ### Pull Request Details The chart hardcoded the ConfigMap data key as `config.alloy`, but the pod template derives the mount subPath / `--config.file` from `alloy.configMap.key` (via the `alloy.config-map.key` helper). Setting `configMap.key: collector.yaml` produced a ConfigMap with key `config.alloy` and a pod expecting `collector.yaml`: ``` reading config path '/etc/alloy/collector.yaml': no such file or directory ``` Wires the existing helper into the ConfigMap template. Default (no key set) renders `config.alloy:` unchanged. Also unblocks `ct install` on the pre-existing `configmap-key-values.yaml` test case. ### How I tested this `helm install configmap-key-verify . -f ci/configmap-key-values.yaml --wait` reaches `STATUS=deployed`; Alloy pod starts cleanly. With default values, ConfigMap key is still `config.alloy`. Golden under `operations/helm/tests/configmap-key/` regenerated (one-line change). ### Issue(s) fixed by this Pull Request N/A — surfaced during work on #6311. ### Notes to the Reviewer CHANGELOG entry uses `(#TBD)` placeholder; I'll fix up with the PR number once it's assigned. ### PR Checklist - [x] Documentation added (`CHANGELOG.md` entry under `Unreleased` > `Bug fixes`) - [x] Tests updated (golden regenerated) - [ ] Config converters updated (N/A) --------- Co-authored-by: Kalle <23356117+kalleep@users.noreply.github.com>
|
I think this looks ok, @petewall any input on this one? |
…g.horizontal.externalHPA When set, the chart omits spec.replicas from the workload AND does not render its own HorizontalPodAutoscaler, enabling clean coexistence with external scalers such as KEDA's ScaledObject-generated HPAs. Strict validation rejects setting both horizontal.enabled and horizontal.externalHPA simultaneously. Default value is false; existing rendered manifests are byte-identical for users who do not set the new field.
Adds three values files under operations/helm/charts/alloy/ci/ covering StatefulSet, Deployment, and the mutual-exclusion validation failure case. The validation-failure file intentionally lacks the -values suffix so ct discovery skips it; an explicit CI shell step in helm-test.yml asserts that helm template fails with the expected "mutually exclusive" message — regression guard the chart-testing tool cannot provide natively. Regenerates README.md via helm-docs and the golden manifests under operations/helm/tests/ for the two positive cases. Adds a CHANGELOG entry under the Unreleased section.
e30a70d to
3984429
Compare
There was a problem hiding this comment.
I love that this is added!
🤖 I have created a release *beep* *boop* --- ## [1.17.0](v1.16.0...v1.17.0) (2026-06-11) ### Features 🌟 * Add gql subcommand ([#6242](#6242)) ([ec09c43](ec09c43)) * **database_observability.mysql:** Add database_observability_wait_event_seconds_total counter ([#6106](#6106)) ([602b0b5](602b0b5)) * **database_observability.mysql:** Refactor bulk table metadata collection ([#6222](#6222)) ([e8d441b](e8d441b)) * **database_observability.mysql:** Refactor schema_details logging strategy ([#6239](#6239)) ([fd51530](fd51530)) * **database_observability.postgres:** Add `exclude_current_user` top-level setting ([#6187](#6187)) ([f019b5e](f019b5e)) * **database_observability.postgres:** Improve monitoring user privileges check ([#6177](#6177)) ([96b50d1](96b50d1)) * **database_observability.postgres:** Make health_check respect user/database exclusions settings ([#6144](#6144)) ([b4ee0a7](b4ee0a7)) * **database_observability.postgres:** Throttle schema details create_statement logs ([#6260](#6260)) ([fcb3d3e](fcb3d3e)) * **database_observability:** Add wait_event_v2 op with pre-classified wait_event_type ([#6105](#6105)) ([f7a1ebd](f7a1ebd)) * **database_observability:** Always extract traceparent in MySQL query_samples collector ([#6081](#6081)) ([bf2b436](bf2b436)) * **database_observability:** Always extract traceparent in Postgres query_samples collector ([#6411](#6411)) ([74d595a](74d595a)) * **database_observability:** Set query_sample, wait_event timestamps at query start for MySQL ([#6291](#6291)) ([a47de00](a47de00)) * **database_observability:** Set timestamp query_sample at query start for Postgres ([#6393](#6393)) ([62d8ecc](62d8ecc)) * **database_observability:** Update wait_event_v2 to a 6-bucket taxonomy and surface Mysql nested events ([#6143](#6143)) ([3df9542](3df9542)) * **faro.receiver:** Support gzip-compressed request bodies ([#6195](#6195)) ([4fa44d2](4fa44d2)) * GraphQL server ([#5580](#5580)) ([5a2562f](5a2562f)) * **helm:** Support externally-managed HPAs via controller.autoscaling.horizontal.externalHPA ([#6311](#6311)) ([a1e61c7](a1e61c7)) * Integration tests for aws firehose and cloudflare logpull ([#6089](#6089)) ([f55f780](f55f780)) * Integration tests for loki.source.azure_event_hubs ([#6113](#6113)) ([8e40165](8e40165)) * Integration tests for loki.source.gcplog ([#6161](#6161)) ([feceb8d](feceb8d)) * **loki.process:** Add regex field to logfmt and json stages ([#4941](#4941)) ([cfbabda](cfbabda)) * **loki.rules.kubernetes:** Add external_labels support ([#6320](#6320)) ([9166a61](9166a61)) * **loki.source.heroku:** Drop github.com/heroku/x package ([#6064](#6064)) ([3382721](3382721)) * Migrate from Docker to Moby ([#6167](#6167)) ([1e2bbf9](1e2bbf9)) * **mimir.rules.kubernetes, loki.rules.kubernetes:** Add configurable `mimir_namespace_separator` and `loki_namespace_separator` arguments to allow using a URL-safe separator ([#5961](#5961)) ([7dba4f1](7dba4f1)) * **otelcol.exporter.prometheus:** Config option to prevent stripping `service.*` attributes ([#6434](#6434)) ([c229b3c](c229b3c)) * **otelcol.exporter.prometheus:** Convert classic histograms to NHCB ([#6281](#6281)) ([46f4fb6](46f4fb6)) * **otelcol:** Add Nginx receiver ([#6141](#6141)) ([fa8d520](fa8d520)) * **prometheus.enrich:** Support multi-label matching ([#5822](#5822)) ([04a1aba](04a1aba)) * **prometheus.relabel:** Add opt-in TTL cache mode ([#6169](#6169)) ([40632c3](40632c3)) * **telemetry:** Add graph connection metrics ([#6243](#6243)) ([4f3bbbe](4f3bbbe)) * **telemetry:** Add pyroscope_forwarded_entries_total metric ([#6244](#6244)) ([65ad64c](65ad64c)) * Update to Beyla 3.9.7 ([#6175](#6175)) ([4015bd9](4015bd9)) * Update to Beyla 3.9.8 ([#6189](#6189)) ([6fffa30](6fffa30)) ### Bug Fixes 🐛 * Address Critical CVE's From Scanner ([#6232](#6232)) ([e713e7a](e713e7a)) * **alloycli:** Use filepath.Base for CLI Use name to fix shell completions ([#6217](#6217)) ([17cfd01](17cfd01)) * **cluster:** Fix nodes failing to join the cluster when TLS is enabled ([#6437](#6437)) ([efbad6d](efbad6d)) * **database_observability.mysql:** Exclude system schemas from MySQL health check ([#6116](#6116)) ([fcae6f4](fcae6f4)) * **database_observability.postgres:** Count error logs when log_timezone is non-UTC ([#6274](#6274)) ([2eaa769](2eaa769)) * **database_observability.postgres:** Do not retain query text in `explain_plans` collector ([#6461](#6461)) ([4c06a64](4c06a64)) * **database_observability:** Exclude more explain plan output keywords ([#6145](#6145)) ([3ff6c14](3ff6c14)) * **deb:** Restart Alloy only on upgrade in postinst script ([#6094](#6094)) ([8c15cb3](8c15cb3)) * **deps:** Pin dependencies ([#6376](#6376)) ([79323b5](79323b5)) * **deps:** Update dependencies for catchpoint, databricks, and snowflake exporters ([#6188](#6188)) ([c1b740c](c1b740c)) * **deps:** Update module go.opentelemetry.io/obi to v0.8.0 [SECURITY] ([#6091](#6091)) ([05c14af](05c14af)) * **documentation:** Fix documentation for loki.rules.kubernetes ([#6088](#6088)) ([61f2b8a](61f2b8a)) * Enforce Singleton For Running Alloy Extension Instances ([#5763](#5763)) ([83da6f0](83da6f0)) * **faro:** Abort on context cancelation ([#6104](#6104)) ([bf733a6](bf733a6)) * Fix bug that caused 'logging' block's 'write_to' to be used after config update even if not set ([#6264](#6264)) ([cba7243](cba7243)) * **graphql:** Update cli flags for consistency ([#6441](#6441)) ([7749d4f](7749d4f)) * **helm:** Honor alloy.configMap.key in templates/configmap.yaml ([#6312](#6312)) ([415af2c](415af2c)) * **integration-tests:** Forward GO_TAGS to k8s integration tests ([#6220](#6220)) ([b00f79c](b00f79c)) * **logging:** Fix startup deadlock when components log before logging config is evaluated ([#6112](#6112)) ([6cdce9e](6cdce9e)) * **loki.process:** Make limit stage shutdown cancelable ([#6215](#6215)) ([20717b5](20717b5)) * **loki.process:** New `action_on_duplicate_timestamp` config attribute to fudge identical log timestamps ([#5615](#5615)) ([7d56f50](7d56f50)) * **loki.process:** No longer mutate rules in stage.truncate causing every config update to reload pipeline when this stage is used ([#6271](#6271)) ([b52a4d8](b52a4d8)) * **loki.process:** Potential deadlock on update with stage and receiver changes ([#6270](#6270)) ([cb22e82](cb22e82)) * **loki.process:** Wrap NewPipeline error correctly in match stage ([#6216](#6216)) ([f3af2dd](f3af2dd)) * **loki.rules.kubernetes:** Add timeout to ruler sync calls ([26170d4](26170d4)) * **loki.source.syslog:** Fix goroutine leak in UDP listener ([#6231](#6231)) ([268b260](268b260)) * **loki:** Clone structured metadata so we can perform fan-out correctly ([#6138](#6138)) ([473244d](473244d)) * **oracledb_exporter:** Support CGO_ENABLED=0 cross-compilation ([#6168](#6168)) ([63ab53d](63ab53d)) * **otelcol.exporter.awss3:** Add missing `unique_key_func_name` attribute ([#6184](#6184)) ([9ad2b44](9ad2b44)) * **prometheus.exporter.oracledb:** Fix issue with custom metrics not appearing when more than one instance of prometheus.exporter.oracledb is used ([#6228](#6228)) ([57de4f4](57de4f4)) * **prometheus.operator.*:** Pass ScrapeNativeHistograms to ScrapeOptions ([#6356](#6356)) ([a44fced](a44fced)) * **remotewrite:** Use blocking send with timeout in test server ([#6208](#6208)) ([a279088](a279088)) * **security:** Update module github.com/jackc/pgx/v5 to v5.9.2 [SECURITY] ([#6326](#6326)) ([bf3ff2e](bf3ff2e)) * **security:** Update x/crypto and x/net for CVEs ([#6336](#6336)) ([4c7b93b](4c7b93b)) * **ui:** Reduce UI dependencies ([#6349](#6349)) ([85e12ba](85e12ba)) * **ui:** Update dependency minor versions ([#6288](#6288)) ([52a28d2](52a28d2)) * Update go to v1.26.4 ([#6418](#6418)) ([51fb7d2](51fb7d2)) * **validation:** Improve type checking of ast.LiteralExpr ([#5916](#5916)) ([d0a1177](d0a1177)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). Co-authored-by: grafana-alloybot[bot] <167359181+grafana-alloybot[bot]@users.noreply.github.com>
This PR contains the following updates: | Package | Update | Change | |---|---|---| | [docker.io/grafana/alloy](https://github.com/grafana/alloy) | minor | `v1.16.3` → `v1.17.0` | --- ### Release Notes <details> <summary>grafana/alloy (docker.io/grafana/alloy)</summary> ### [`v1.17.0`](https://github.com/grafana/alloy/releases/tag/v1.17.0) [Compare Source](grafana/alloy@v1.16.3...v1.17.0) ##### Features 🌟 - Add gql subcommand ([#​6242](grafana/alloy#6242)) ([ec09c43](grafana/alloy@ec09c43)) ([@​jharvey10](https://github.com/jharvey10)) - **database\_observability.mysql:** Add database\_observability\_wait\_event\_seconds\_total counter ([#​6106](grafana/alloy#6106)) ([602b0b5](grafana/alloy@602b0b5)) ([@​gaantunes](https://github.com/gaantunes)) - **database\_observability.mysql:** Refactor bulk table metadata collection ([#​6222](grafana/alloy#6222)) ([e8d441b](grafana/alloy@e8d441b)) ([@​cristiangreco](https://github.com/cristiangreco)) - **database\_observability.mysql:** Refactor schema\_details logging strategy ([#​6239](grafana/alloy#6239)) ([fd51530](grafana/alloy@fd51530)) ([@​cristiangreco](https://github.com/cristiangreco)) - **database\_observability.postgres:** Add `exclude_current_user` top-level setting ([#​6187](grafana/alloy#6187)) ([f019b5e](grafana/alloy@f019b5e)) ([@​cristiangreco](https://github.com/cristiangreco), [@​matthewnolf](https://github.com/matthewnolf)) - **database\_observability.postgres:** Improve monitoring user privileges check ([#​6177](grafana/alloy#6177)) ([96b50d1](grafana/alloy@96b50d1)) ([@​cristiangreco](https://github.com/cristiangreco)) - **database\_observability.postgres:** Make health\_check respect user/database exclusions settings ([#​6144](grafana/alloy#6144)) ([b4ee0a7](grafana/alloy@b4ee0a7)) ([@​cristiangreco](https://github.com/cristiangreco)) - **database\_observability.postgres:** Throttle schema details create\_statement logs ([#​6260](grafana/alloy#6260)) ([fcb3d3e](grafana/alloy@fcb3d3e)) ([@​cristiangreco](https://github.com/cristiangreco)) - **database\_observability:** Add wait\_event\_v2 op with pre-classified wait\_event\_type ([#​6105](grafana/alloy#6105)) ([f7a1ebd](grafana/alloy@f7a1ebd)) ([@​gaantunes](https://github.com/gaantunes)) - **database\_observability:** Always extract traceparent in MySQL query\_samples collector ([#​6081](grafana/alloy#6081)) ([bf2b436](grafana/alloy@bf2b436)) ([@​fridgepoet](https://github.com/fridgepoet)) - **database\_observability:** Always extract traceparent in Postgres query\_samples collector ([#​6411](grafana/alloy#6411)) ([74d595a](grafana/alloy@74d595a)) ([@​fridgepoet](https://github.com/fridgepoet)) - **database\_observability:** Set query\_sample, wait\_event timestamps at query start for MySQL ([#​6291](grafana/alloy#6291)) ([a47de00](grafana/alloy@a47de00)) ([@​fridgepoet](https://github.com/fridgepoet)) - **database\_observability:** Set timestamp query\_sample at query start for Postgres ([#​6393](grafana/alloy#6393)) ([62d8ecc](grafana/alloy@62d8ecc)) ([@​fridgepoet](https://github.com/fridgepoet)) - **database\_observability:** Update wait\_event\_v2 to a 6-bucket taxonomy and surface Mysql nested events ([#​6143](grafana/alloy#6143)) ([3df9542](grafana/alloy@3df9542)) ([@​gaantunes](https://github.com/gaantunes), [@​cristiangreco](https://github.com/cristiangreco)) - **faro.receiver:** Support gzip-compressed request bodies ([#​6195](grafana/alloy#6195)) ([4fa44d2](grafana/alloy@4fa44d2)) ([@​d0ugal](https://github.com/d0ugal)) - GraphQL server ([#​5580](grafana/alloy#5580)) ([5a2562f](grafana/alloy@5a2562f)) ([@​jharvey10](https://github.com/jharvey10)) - **helm:** Support externally-managed HPAs via controller.autoscaling.horizontal.externalHPA ([#​6311](grafana/alloy#6311)) ([a1e61c7](grafana/alloy@a1e61c7)) ([@​jmichalek132](https://github.com/jmichalek132)) - Integration tests for aws firehose and cloudflare logpull ([#​6089](grafana/alloy#6089)) ([f55f780](grafana/alloy@f55f780)) ([@​x1unix](https://github.com/x1unix)) - Integration tests for loki.source.azure\_event\_hubs ([#​6113](grafana/alloy#6113)) ([8e40165](grafana/alloy@8e40165)) ([@​x1unix](https://github.com/x1unix)) - Integration tests for loki.source.gcplog ([#​6161](grafana/alloy#6161)) ([feceb8d](grafana/alloy@feceb8d)) ([@​x1unix](https://github.com/x1unix)) - **loki.process:** Add regex field to logfmt and json stages ([#​4941](grafana/alloy#4941)) ([cfbabda](grafana/alloy@cfbabda)) ([@​timonegk](https://github.com/timonegk)) - **loki.rules.kubernetes:** Add external\_labels support ([#​6320](grafana/alloy#6320)) ([9166a61](grafana/alloy@9166a61)) ([@​gianvetter](https://github.com/gianvetter)) - **loki.source.heroku:** Drop github.com/heroku/x package ([#​6064](grafana/alloy#6064)) ([3382721](grafana/alloy@3382721)) ([@​x1unix](https://github.com/x1unix)) - Migrate from Docker to Moby ([#​6167](grafana/alloy#6167)) ([1e2bbf9](grafana/alloy@1e2bbf9)) ([@​x1unix](https://github.com/x1unix)) - **mimir.rules.kubernetes, loki.rules.kubernetes:** Add configurable `mimir_namespace_separator` and `loki_namespace_separator` arguments to allow using a URL-safe separator ([#​5961](grafana/alloy#5961)) ([7dba4f1](grafana/alloy@7dba4f1)) ([@​QuentinBisson](https://github.com/QuentinBisson), [@​clayton-cornell](https://github.com/clayton-cornell)) - **otelcol.exporter.prometheus:** Config option to prevent stripping `service.*` attributes ([#​6434](grafana/alloy#6434)) ([c229b3c](grafana/alloy@c229b3c)) ([@​jcreixell](https://github.com/jcreixell)) - **otelcol.exporter.prometheus:** Convert classic histograms to NHCB ([#​6281](grafana/alloy#6281)) ([46f4fb6](grafana/alloy@46f4fb6)) ([@​madaraszg-tulip](https://github.com/madaraszg-tulip)) - **otelcol:** Add Nginx receiver ([#​6141](grafana/alloy#6141)) ([fa8d520](grafana/alloy@fa8d520)) ([@​henworth](https://github.com/henworth), [@​clayton-cornell](https://github.com/clayton-cornell), [@​blewis12](https://github.com/blewis12)) - **prometheus.enrich:** Support multi-label matching ([#​5822](grafana/alloy#5822)) ([04a1aba](grafana/alloy@04a1aba)) ([@​dtrejod](https://github.com/dtrejod)) - **prometheus.relabel:** Add opt-in TTL cache mode ([#​6169](grafana/alloy#6169)) ([40632c3](grafana/alloy@40632c3)) ([@​kgeckhart](https://github.com/kgeckhart)) - **telemetry:** Add graph connection metrics ([#​6243](grafana/alloy#6243)) ([4f3bbbe](grafana/alloy@4f3bbbe)) ([@​theSuess](https://github.com/theSuess)) - **telemetry:** Add pyroscope\_forwarded\_entries\_total metric ([#​6244](grafana/alloy#6244)) ([65ad64c](grafana/alloy@65ad64c)) ([@​theSuess](https://github.com/theSuess)) - Update to Beyla 3.9.7 ([#​6175](grafana/alloy#6175)) ([4015bd9](grafana/alloy@4015bd9)) ([@​rafaelroquetto](https://github.com/rafaelroquetto)) - Update to Beyla 3.9.8 ([#​6189](grafana/alloy#6189)) ([6fffa30](grafana/alloy@6fffa30)) ([@​skl](https://github.com/skl)) ##### Bug Fixes 🐛 - Address Critical CVE's From Scanner ([#​6232](grafana/alloy#6232)) ([e713e7a](grafana/alloy@e713e7a)) ([@​blewis12](https://github.com/blewis12)) - **alloycli:** Use filepath.Base for CLI Use name to fix shell completions ([#​6217](grafana/alloy#6217)) ([17cfd01](grafana/alloy@17cfd01)) ([@​IngmarStein](https://github.com/IngmarStein)) - **cluster:** Fix nodes failing to join the cluster when TLS is enabled ([#​6437](grafana/alloy#6437)) ([efbad6d](grafana/alloy@efbad6d)) ([@​kgeckhart](https://github.com/kgeckhart)) - **database\_observability.mysql:** Exclude system schemas from MySQL health check ([#​6116](grafana/alloy#6116)) ([fcae6f4](grafana/alloy@fcae6f4)) ([@​matthewnolf](https://github.com/matthewnolf)) - **database\_observability.postgres:** Count error logs when log\_timezone is non-UTC ([#​6274](grafana/alloy#6274)) ([2eaa769](grafana/alloy@2eaa769)) ([@​gaantunes](https://github.com/gaantunes), [@​cristiangreco](https://github.com/cristiangreco)) - **database\_observability.postgres:** Do not retain query text in `explain_plans` collector ([#​6461](grafana/alloy#6461)) ([4c06a64](grafana/alloy@4c06a64)) ([@​cristiangreco](https://github.com/cristiangreco)) - **database\_observability:** Exclude more explain plan output keywords ([#​6145](grafana/alloy#6145)) ([3ff6c14](grafana/alloy@3ff6c14)) ([@​cristiangreco](https://github.com/cristiangreco)) - **deb:** Restart Alloy only on upgrade in postinst script ([#​6094](grafana/alloy#6094)) ([8c15cb3](grafana/alloy@8c15cb3)) ([@​guoard](https://github.com/guoard), [@​jharvey10](https://github.com/jharvey10)) - **deps:** Pin dependencies ([#​6376](grafana/alloy#6376)) ([79323b5](grafana/alloy@79323b5)) - **deps:** Update dependencies for catchpoint, databricks, and snowflake exporters ([#​6188](grafana/alloy#6188)) ([c1b740c](grafana/alloy@c1b740c)) ([@​Dasomeone](https://github.com/Dasomeone)) - **deps:** Update module go.opentelemetry.io/obi to v0.8.0 \[SECURITY] ([#​6091](grafana/alloy#6091)) ([05c14af](grafana/alloy@05c14af)) - **documentation:** Fix documentation for loki.rules.kubernetes ([#​6088](grafana/alloy#6088)) ([61f2b8a](grafana/alloy@61f2b8a)) ([@​timonegk](https://github.com/timonegk), [@​clayton-cornell](https://github.com/clayton-cornell)) - Enforce Singleton For Running Alloy Extension Instances ([#​5763](grafana/alloy#5763)) ([83da6f0](grafana/alloy@83da6f0)) ([@​blewis12](https://github.com/blewis12), [@​clayton-cornell](https://github.com/clayton-cornell)) - **faro:** Abort on context cancelation ([#​6104](grafana/alloy#6104)) ([bf733a6](grafana/alloy@bf733a6)) ([@​kalleep](https://github.com/kalleep)) - Fix bug that caused 'logging' block's 'write\_to' to be used after config update even if not set ([#​6264](grafana/alloy#6264)) ([cba7243](grafana/alloy@cba7243)) ([@​ptodev](https://github.com/ptodev)) - **graphql:** Update cli flags for consistency ([#​6441](grafana/alloy#6441)) ([7749d4f](grafana/alloy@7749d4f)) ([@​jharvey10](https://github.com/jharvey10)) - **helm:** Honor alloy.configMap.key in templates/configmap.yaml ([#​6312](grafana/alloy#6312)) ([415af2c](grafana/alloy@415af2c)) ([@​jmichalek132](https://github.com/jmichalek132), [@​kalleep](https://github.com/kalleep)) - **integration-tests:** Forward GO\_TAGS to k8s integration tests ([#​6220](grafana/alloy#6220)) ([b00f79c](grafana/alloy@b00f79c)) ([@​thampiotr](https://github.com/thampiotr)) - **logging:** Fix startup deadlock when components log before logging config is evaluated ([#​6112](grafana/alloy#6112)) ([6cdce9e](grafana/alloy@6cdce9e)) ([@​kgeckhart](https://github.com/kgeckhart)) - **loki.process:** Make limit stage shutdown cancelable ([#​6215](grafana/alloy#6215)) ([20717b5](grafana/alloy@20717b5)) ([@​boinger](https://github.com/boinger)) - **loki.process:** New `action_on_duplicate_timestamp` config attribute to fudge identical log timestamps ([#​5615](grafana/alloy#5615)) ([7d56f50](grafana/alloy@7d56f50)) ([@​boussaffawalid](https://github.com/boussaffawalid)) - **loki.process:** No longer mutate rules in stage.truncate causing every config update to reload pipeline when this stage is used ([#​6271](grafana/alloy#6271)) ([b52a4d8](grafana/alloy@b52a4d8)) ([@​kalleep](https://github.com/kalleep)) - **loki.process:** Potential deadlock on update with stage and receiver changes ([#​6270](grafana/alloy#6270)) ([cb22e82](grafana/alloy@cb22e82)) ([@​kalleep](https://github.com/kalleep)) - **loki.process:** Wrap NewPipeline error correctly in match stage ([#​6216](grafana/alloy#6216)) ([f3af2dd](grafana/alloy@f3af2dd)) ([@​boinger](https://github.com/boinger)) - **loki.rules.kubernetes:** Add timeout to ruler sync calls ([26170d4](grafana/alloy@26170d4)) ([@​QuentinBisson](https://github.com/QuentinBisson)) - **loki.source.syslog:** Fix goroutine leak in UDP listener ([#​6231](grafana/alloy#6231)) ([268b260](grafana/alloy@268b260)) ([@​x1unix](https://github.com/x1unix)) - **loki:** Clone structured metadata so we can perform fan-out correctly ([#​6138](grafana/alloy#6138)) ([473244d](grafana/alloy@473244d)) ([@​kalleep](https://github.com/kalleep)) - **oracledb\_exporter:** Support CGO\_ENABLED=0 cross-compilation ([#​6168](grafana/alloy#6168)) ([63ab53d](grafana/alloy@63ab53d)) ([@​korniltsev-grafanista](https://github.com/korniltsev-grafanista)) - **otelcol.exporter.awss3:** Add missing `unique_key_func_name` attribute ([#​6184](grafana/alloy#6184)) ([9ad2b44](grafana/alloy@9ad2b44)) ([@​kalleep](https://github.com/kalleep)) - **prometheus.exporter.oracledb:** Fix issue with custom metrics not appearing when more than one instance of prometheus.exporter.oracledb is used ([#​6228](grafana/alloy#6228)) ([57de4f4](grafana/alloy@57de4f4)) ([@​ptodev](https://github.com/ptodev)) - **prometheus.operator.\*:** Pass ScrapeNativeHistograms to ScrapeOptions ([#​6356](grafana/alloy#6356)) ([a44fced](grafana/alloy@a44fced)) ([@​sberz](https://github.com/sberz)) - **remotewrite:** Use blocking send with timeout in test server ([#​6208](grafana/alloy#6208)) ([a279088](grafana/alloy@a279088)) ([@​kgeckhart](https://github.com/kgeckhart)) - **security:** Update module github.com/jackc/pgx/v5 to v5.9.2 \[SECURITY] ([#​6326](grafana/alloy#6326)) ([bf3ff2e](grafana/alloy@bf3ff2e)) - **security:** Update x/crypto and x/net for CVEs ([#​6336](grafana/alloy#6336)) ([4c7b93b](grafana/alloy@4c7b93b)) ([@​thampiotr](https://github.com/thampiotr)) - **ui:** Reduce UI dependencies ([#​6349](grafana/alloy#6349)) ([85e12ba](grafana/alloy@85e12ba)) ([@​jharvey10](https://github.com/jharvey10)) - **ui:** Update dependency minor versions ([#​6288](grafana/alloy#6288)) ([52a28d2](grafana/alloy@52a28d2)) ([@​jharvey10](https://github.com/jharvey10)) - Update go to v1.26.4 ([#​6418](grafana/alloy#6418)) ([51fb7d2](grafana/alloy@51fb7d2)) ([@​kalleep](https://github.com/kalleep)) - **validation:** Improve type checking of ast.LiteralExpr ([#​5916](grafana/alloy#5916)) ([d0a1177](grafana/alloy@d0a1177)) ([@​kalleep](https://github.com/kalleep)) #### Upgrading Read the [release notes] for specific instructions on upgrading from older versions: [release notes]: https://grafana.com/docs/alloy/v1.17/release-notes/ #### Installation Refer to our [installation guide] for how to install Grafana Alloy. [installation guide]: https://grafana.com/docs/alloy/v1.17/get-started/install/ </details> --- ### Configuration 📅 **Schedule**: (UTC) - Branch creation - At any time (no schedule defined) - Automerge - At any time (no schedule defined) 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Mend Renovate](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yMTQuNSIsInVwZGF0ZWRJblZlciI6IjQzLjIxNC41IiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->
Brief description of Pull Request
Adds
controller.autoscaling.horizontal.externalHPAso KEDA (and other external scalers) can ownspec.replicaswithout fighting the chart. Defaultfalse— no behavior change for existing users.(The configmap-key fix originally bundled here was moved to #6312 (now merged) per @kalleep's request.)
Pull Request Details
When
controller.autoscaling.horizontal.externalHPA: true:spec.replicasfrom the StatefulSet / Deployment.HorizontalPodAutoscaler.Mutually exclusive with
horizontal.enabled. Setting both fails the template with a clear multi-line message.Behavior matrix:
autoscaling.enabledhorizontal.enabledhorizontal.externalHPAfalse(default)false(default)false(default)replicas. No HPA. (today's default)truefalsereplicas. Renders deprecated HPA. (today's behavior)truefalsereplicas. Renders new HPA. (today's behavior)truereplicas. No HPA rendered. (NEW)Upgrade note: flipping
externalHPAfromfalse→trueon an existing release causes a one-time single-cycle dip to 1 replica on the nexthelm upgrade. Helm removes the field via{"spec":{"replicas":null}}, which Kubernetes resets to default 1 (see helm/helm#12650). The external HPA corrects it within its next polling interval. Documented in thevalues.yamlcomment.How I tested this
Reproduced the bug (pre-fix): kind + KEDA 2.13 + Prometheus + alloy-operator + alloy chart 1.8.1.
AlloyCR withcontroller.replicas: 5, autoscaling off, KEDAScaledObjectforcing target=10. Operator reconciles every ~15s and assertsreplicas:5; KEDA briefly wins between reconciles:5-min capture:
replicas:5= 59 occurrences,replicas:(8|9|10)= 1.Patched chart (post-fix): monotonic ramp 1→5→8, stable for the rest of the capture window:
kubectl get hpa -o name→ onlykeda-hpa-alloy-repro.kubectl get sts alloy-repro -o yaml | yq '.spec | has("replicas")'→false.Template smoke tests (
helm template):replicas: 1, no HPA. Existing behavior unchanged.externalHPA: true:yq '.spec | has("replicas")'→falseon StatefulSet AND Deployment, no HPA.helm templatefails with the multi-line "mutually exclusive" message. Newlines render correctly (printfwrapping per helm/helm#9981).ct lint: clean on all three newci/*-values.yamlfiles.ct install: the two new positive CI files install cleanly. Verified via directhelm install --waitbecausect installonmainis blocked by a pre-existingconfigmap-key-values.yamlissue (fixed in #6312 (merged)).make generate-helm-tests: new goldens underoperations/helm/tests/create-statefulset-external-hpa/andoperations/helm/tests/create-deployment-external-hpa/. Both have nospec.replicasand no HPA file.helm-docs: README.md updated with the newexternalHPArow and the upgrade-dip note.Issue(s) fixed by this Pull Request
Fixes #6310
Notes to the Reviewer
The custom shell step in
helm-test.yml(Assert external HPA validation failure) asserts that the validation file causeshelm templateto fail.ctdoesn't have a native "this values file MUST fail" mode. The cleaner alternative ishelm-unittest(whichk8s-monitoring-helmuses for the same kind of thing), but that's a new tool for this chart and felt out of scope. Happy to switch if you'd prefer.The negative CI values file intentionally drops the
-valuessuffix soct/make generate-helm-testsdiscovery skips it.Chart.yamlnot bumped — followed the existing pattern of adding toUnreleasedand letting maintainers bump at release time. Tell me if I should bump it.Local Helm was 4.2.0; CI uses 3.10.3. The committed goldens may have minor whitespace deltas from what CI renders. I'll iterate if
regenerate-testsflags anything.PR Checklist
values.yamldoc comment +README.mdauto-generated +CHANGELOG.mdentry under Unreleased)ci/*-values.yamlfiles + CI shell-step assertion + regeneratedoperations/helm/tests/goldens)