Repository navigation
Description
Problem
Since #2224 the object-store settings (ATE_STORAGE_BACKEND, AWS_REGION, AWS_ENDPOINT_URL, AWS_S3_USE_PATH_STYLE, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY) are consumed by three containers that must agree:
- the
snapshot-pluginsidecar inate-api-server(cleanup, copy) - the
snapshot-pluginsidecar inatelet(checkpoint upload, restore download) - the
ateletcontainer itself (sandbox asset downloads viapkg/objectstorage; stays until that path moves off object storage)
Each is configured with its own inline env: block. The GCS default is repeated three times in manifests/ate-install/{ate-api-server,atelet}.yaml, and the rustfs settings are repeated three times across manifests/ate-install/kind/kustomization.yaml and manifests/ate-install/kind/atelet/kustomization.yaml. Nothing enforces they match. If they drift, ate-api-server deletes or copies snapshots in one bucket while atelet writes to another, and the failure surfaces only as a runtime NotFound on cleanup or restore.
That drift already happens on one supported path. ate-setup --deploy-ate-apiserver renders the bare ate-api-server.yaml with no kind branch (DeployAteAPIServer in cmd/ate-setup/internal/steps/deploy.go), while DeployAtelet switches to the kind/atelet overlay when --kind is set. On a kind cluster a targeted API-server redeploy therefore gets a snapshot-plugin sidecar pointed at GCS with no credentials, while atelet keeps writing to rustfs. The ATE_STORAGE_BACKEND refusal added to ate-api-server in #2224 does not catch this: the variable is on the sidecar, where it belongs; it is just the wrong value.
Proposal
Do what the install already does for OTLP (ate-otel-config) and for PostgreSQL (CreateAPIServerEnvVars: ConfigMap + Secret via optional envFrom, ate.dev/env-hash annotation so a change rolls the pods):
- Add
ate-storage-config(ConfigMap: backend, region, endpoint, path style) andate-storage-credentials(Secret: access key/secret, present only where static keys are used, i.e. kind/rustfs). Base ships the GCS ConfigMap; the kind overlay ships the rustfs ConfigMap and Secret. - Replace the inline storage
env:blocks on the three consumers withenvFromreferencing both,optional: trueon the Secret. Attach them only to the containers listed above; theate-api-servercontainer must not get them orrejectStorageEnvwill exit the process. - Have
ate-setupapply the ConfigMap/Secret inDeployAteSystem,DeployAteAPIServer, andDeployAtelet(next toapplyOtelConfig), and giveDeployAteAPIServerthe same kind branchDeployAtelethas, or make it unnecessary by sourcing everything from the ConfigMap. - Delete the duplicated
env:copies in the kind overlays and the explanatory comments that point at them.
Notes
env:entries overrideenvFrom, so any remaining inline value silently wins. Step 4 is what makes the ConfigMap authoritative; verify withkubectl kustomize manifests/ate-install/kind --load-restrictor LoadRestrictionsNone.- Production GKE/EKS installs use workload/pod identity; the Secret is a kind convenience and the docs should say so.
- When sandbox asset downloads leave
pkg/objectstorage(separate issue), theateletcontainer drops out of the consumer list; the ConfigMap shape does not change. - Not GA-blocking: the shipped overlays are internally consistent today, and the known bad path is a dev-loop redeploy on kind.
Follow-up to #2224.
Activity
skamboj commentedon Oct 16, 2026
+1, and here's a reason for this beyond kind. We run an on-prem install against an S3-compatible store: static access keys, path-style addressing, its own endpoint. Today that takes an overlay that sets the same S3 settings on both
objectstore-pluginsidecars. That's the drift this issue describes, outside kind.Two updates to the consumer list since the issue was written:
objectstore-pluginsidecars read these settings now (Rename the snapshot-plugin sidecar, image and flag to objectstore-plugin #2540 renamed them fromsnapshot-plugin). atelet's own container stopped reading them in Fetch private sandbox assets through the object-store plugin #2439.ATE_STORAGE_BACKENDis set on it, as ate-api-server's does. So step 2's warning covers both main containers: theenvFromgoes on the sidecars only.(The kind redeploy in the Problem section was fixed by #2682.)
The one change that would let us drop the overlay is for
ate-setupto renderate-storage-configfrom settings, the wayapienv.gorenders the PostgreSQL ConfigMap and Secret, instead of applying a static copy. As proposed, base ships the GCS values and only the kind overlay ships S3 values, so a non-kind S3 install would still need an overlay. Andate-setupapplies withForce: true, so a ConfigMap edited after install goes back to GCS on the next run. Settings next to the existingstorage.bucketNamewould do it:storage.backend:gcsors3storage.s3.endpointstorage.s3.regionstorage.s3.pathStyleFor credentials, either of these works for us:
ate-storage-credentials, likeateapi.postgres.readWrite.connectionStringdoes for PostgreSQL;ate-storage-credentialsthatate-setupleaves alone outside kind, so it can come from an external secret manager.One wording request for the Notes: on-prem S3-compatible stores (Ceph RGW, MinIO and the like) usually have no workload identity, so static keys are their production path. Could the docs call static keys supported for those stores, rather than "a kind convenience"?
SamPriyadarshi commentedon Oct 19, 2026
I'd like to pick this up. Since the issue was filed, only the two objectstore-plugin sidecars read these settings (#2439), and the kind redeploy case is fixed (#2682), so here's the scope I have in mind for a first PR:
ate-storage-configConfigMap (base:ATE_STORAGE_BACKEND=gcs; kind: the rustfs S3 settings) and an optionalate-storage-credentialsSecret (kind only), consumed viaenvFromby the two sidecars only. The inlineenv:copies in the base manifests and both kind overlays go away.ate-otel-config(deploy ate-system,deploy apiserver,deploy atelet), and stamps a digest of them on ate-api-server and atelet so a config change rolls both.envFrominstead of copying the sidecar'senv.One thing I ran into: kind's rustfs bucket-init Job can't be pointed at the shared Secret, because a Job's pod template is immutable and the change breaks
deploy ate-systemon existing kind clusters. So rustfs keeps its values inline, and a unit test checks they match the shared config.I have this working locally. Effective container env is unchanged on every overlay, and it passes the unit tests,
hack/verify-all.shand a kind run: installmain, upgrade, single-component redeploys, roll-on-change, and the demo e2e suites.Rendering the ConfigMap/Secret from installer settings (
storage.backend,storage.s3.*) for non-kind S3 installs, as skamboj suggested, would be a follow-up PR.Is it OK to do this as a first PR and handle the installer settings in a follow-up?
ILLUM1N0X commentedon Oct 23, 2026
Thanks for suggesting to take this SamPriyadarshi
I think it makes sense to split this into multiple PRs