Description
At EdgeZero revision 055f7e94e53f3b7d9551ae078db7f015930ba953, a Fastly staged deploy can drop a deployment-supplied logical-to-physical store-name mapping unless the same mapping already exists in the production runtime-env store in service-scoped form.
The deploy action received:
EDGEZERO__STORES__SECRETS__TRUSTED_SERVER_SECRETS__NAME=ts_secrets
However, ts deploy --adapter fastly --staging reconciled the staging twin without that mapping. The deployed application then tried to open the logical name trusted_server_secrets instead of the linked physical name ts_secrets and failed during startup.
Reproduction
-
Declare logical secret store trusted_server_secrets in edgezero.toml.
-
Link a physical Fastly Secret Store as ts_secrets.
-
Ensure the production edgezero_runtime_env store has either no mapping or only the legacy unscoped mapping. Do not add the service-scoped mapping.
-
Export:
export EDGEZERO__STORES__SECRETS__TRUSTED_SERVER_SECRETS__NAME=ts_secrets
-
Run a staged Fastly deploy.
-
Inspect edgezero_runtime_env_staging_<SERVICE_ID>.
The staging twin contains the generated config selector but not:
EDGEZERO__SERVICES__<SERVICE_ID>__STORES__SECRETS__TRUSTED_SERVER_SECRETS__NAME=ts_secrets
In the observed deployment, reconciliation also deleted the legacy unscoped mapping from the staging twin.
Cause
staging_entries_from_production copies only current-service, service-scoped production entries and adds config selectors. It does not merge store-name mappings supplied through the deploy process environment. This is safe with respect to cross-service ownership, but it makes the documented deploy-time mapping ineffective when provision has not first migrated the production entry to service-scoped form.
Expected behavior
A staged deploy should persist deployment-supplied store-name mappings under the current service scope before linking the staging runtime-env store. It should not require a separate provisioning run when the deploy action already received the mapping.
Production deploys should preserve the same invariant so later staged deploys can mirror the scoped mapping.
Impact
The deploy and health check can appear successful while normal application startup fails when it first resolves a secret reference. The /health path may not exercise secret resolution.
Workaround
Upsert the service-scoped mapping into both the production runtime-env store and the current staging twin. Once production has the scoped entry, later staged deploys mirror it correctly.
Acceptance criteria
- A staged deploy with a non-default
EDGEZERO__STORES__*__NAME value writes the corresponding service-scoped entry to the staging twin.
- The mapping works when production has no prior entry or only a legacy unscoped entry.
- Reconciliation does not delete a mapping supplied to the current deploy.
- A focused test covers the deploy-environment mapping plus service-scoped staging reconciliation.
Description
At EdgeZero revision
055f7e94e53f3b7d9551ae078db7f015930ba953, a Fastly staged deploy can drop a deployment-supplied logical-to-physical store-name mapping unless the same mapping already exists in the production runtime-env store in service-scoped form.The deploy action received:
However,
ts deploy --adapter fastly --stagingreconciled the staging twin without that mapping. The deployed application then tried to open the logical nametrusted_server_secretsinstead of the linked physical namets_secretsand failed during startup.Reproduction
Declare logical secret store
trusted_server_secretsinedgezero.toml.Link a physical Fastly Secret Store as
ts_secrets.Ensure the production
edgezero_runtime_envstore has either no mapping or only the legacy unscoped mapping. Do not add the service-scoped mapping.Export:
export EDGEZERO__STORES__SECRETS__TRUSTED_SERVER_SECRETS__NAME=ts_secretsRun a staged Fastly deploy.
Inspect
edgezero_runtime_env_staging_<SERVICE_ID>.The staging twin contains the generated config selector but not:
In the observed deployment, reconciliation also deleted the legacy unscoped mapping from the staging twin.
Cause
staging_entries_from_productioncopies only current-service, service-scoped production entries and adds config selectors. It does not merge store-name mappings supplied through the deploy process environment. This is safe with respect to cross-service ownership, but it makes the documented deploy-time mapping ineffective whenprovisionhas not first migrated the production entry to service-scoped form.Expected behavior
A staged deploy should persist deployment-supplied store-name mappings under the current service scope before linking the staging runtime-env store. It should not require a separate provisioning run when the deploy action already received the mapping.
Production deploys should preserve the same invariant so later staged deploys can mirror the scoped mapping.
Impact
The deploy and health check can appear successful while normal application startup fails when it first resolves a secret reference. The
/healthpath may not exercise secret resolution.Workaround
Upsert the service-scoped mapping into both the production runtime-env store and the current staging twin. Once production has the scoped entry, later staged deploys mirror it correctly.
Acceptance criteria
EDGEZERO__STORES__*__NAMEvalue writes the corresponding service-scoped entry to the staging twin.