When one unchanged image starts in staging and in production, what decides which set of values it comes up with?
answer
- the artifact cannot know where it is
- the deployment supplies the selection input
- a stage name, or an already-merged set
- narrower layer wins, per key not per document
- resolve before serving; missing required key is fatal
basics
~20 sThe deployment decides, because it is the only party that knows where it is deploying. It either hands the workload a stage name that selects a named set, or hands it a set already merged from shared defaults plus that stage's overrides, resolved once at start-up.
solid answer
~50 sThe artifact cannot know which environment it is in, so selection is always something the deployment supplies. It takes one of three shapes. The deployment can supply a **stage name**, and the process resolves the matching named set. It can supply an **already-merged set**: shared defaults plus a per-stage overlay, combined by the tooling before the workload spec is submitted, so the process sees one flat resolved set and knows nothing about the layering. Or the artifact can carry **safe defaults** and the deployment supply only the deltas for that stage. Whichever shape you pick, two things matter: one documented precedence order — narrower beats broader, and a value that is explicitly set to empty is not the same as one left unset — and resolution completing before the process starts serving, with a missing required value ending the start-up loudly instead of defaulting to something plausible.
code
yaml · 15 lines# shared defaults - inherited by every stage
renderQueueSize: 32
reportRetentionDays: 30
logLevel: info
storageEndpoint: null # required: no value is safe everywhere
---
# staging overlay - only what differs
logLevel: debug
storageEndpoint: reports-staging.internal:8080
---
# production overlay - only what differs
renderQueueSize: 128
storageEndpoint: reports.internal:8080go deeper
Remember the direction: the deployment tells the workload which environment it is in, never the other way round. The process reads the values it was handed as it starts.
Be able to describe the layering and its precedence — shared defaults, a per-stage overlay, per-key last-writer-wins — and say where the merge happens and what the process therefore sees.
Show the operational consequences: a start-up check that exits non-zero naming the missing key, a rendered set you can diff between environments, and no silent fallback when the stage name is absent.
Decide the one selection shape your organisation uses and what the platform guarantees about it — that resolved sets are renderable and reviewable, and that precedence is a documented property rather than per-team folklore.
## What "selection" actually is The artifact is fixed and identical everywhere, so it cannot know which environment it woke up in. Something outside it does: the deployment. **Selection is the step where the environment's identity turns into a concrete set of values the process can read**, and it happens in the window between the workload being placed and the process beginning to serve. The interview-grade answer names where that step happens, because that is what decides when a bad value is caught and what a change costs. ## The three shapes selection takes 1. **A stage name supplied by the deployment.** The deployment hands over exactly one value — the stage name — and the process, or a small start-up wrapper, uses it to choose a named set from documents it can reach. Minimal plumbing. The cost is that those documents have to live somewhere: if they ship inside the artifact, every value change becomes a rebuild, and every environment's values travel everywhere the artifact goes. 2. **An overlay merged before submission.** A shared defaults document plus a per-stage document holding only that stage's differences. The tooling that prepares the deployment merges the two and submits the result. The workload receives one flat, already-resolved set and has no idea layering happened. 3. **Defaults inside the artifact, deltas from outside.** The artifact ships values that are safe everywhere, and the deployment supplies only what genuinely differs for this stage. The supplied set stays small and readable, and the diff between two environments is literally the file. | | Where the merge happens | What the process sees | When a bad value surfaces | Cost of changing a shared default | |---|---|---|---|---| | Stage name selects a set | inside the process, at start-up | the stage name plus its own documents | at start-up, inside the workload | a rebuild if the sets ship in the artifact | | Overlay merged first | in the deployment tooling | one flat resolved set | before submission, if the tooling validates | edit one shared document, redeploy | | Defaults plus deltas | split: defaults inside, deltas outside | defaults overridden by supplied deltas | at start-up | a rebuild for the default, a redeploy for the delta | ## Precedence, and the rules that make it debuggable Whatever the shape, write down one order and keep it: - **Narrower beats broader.** Per-stage beats shared; a per-instance override, if you allow one at all, beats per-stage. - **Last writer wins, per key, not per document.** A stage overlay that sets two keys must not silently discard the eighty it did not mention. - **Unset is not empty.** A key explicitly set to an empty value is a decision; a key nobody mentioned is an omission. Collapsing the two is how a production run ends up writing to nowhere. - **The resolved set must be printable.** Being able to render exactly what a stage resolves to — with credential values suppressed — is what turns an argument about precedence into a diff. ## When resolution happens, and what that implies Resolution normally completes **once, at start-up**, before the process serves anything. Whether and how a running process later notices a changed value is a separate subject; what matters for selection is that the process has a complete, decided set before it accepts its first unit of work. That timing is what makes start-up the right place to enforce the contract: - Every value the artifact **requires** and cannot safely default should be declared, checked once, and, if missing, end the start-up with a non-zero exit that names the key. - Failing at start-up means the deployment fails visibly, in the environment where it was supplied, before anything routes traffic to it. - The alternative — start anyway, discover the gap at the first request that needs it — moves the failure to whichever hour that code path first runs, usually with a worse audience. ## Where selection goes wrong - **A stage name with a fallback.** If an unsupplied stage name quietly resolves to one of the stages, a misconfigured production deployment comes up looking healthy while pointed at another environment's dependencies. An unsupplied stage name should be fatal. - **A missing key filled with a plausible default.** An empty endpoint or a zero timeout substituted for "nobody told me" turns a configuration error into a behavioural one. - **Layering the artifact cannot see.** Where merging happens in tooling, the workload cannot explain its own values; keep the rendered set available as an output of the deployment so the answer to "where did this value come from" exists. - **Divergent spelling.** One environment's set naming a key slightly differently is not an override at all — it is a new key that nothing reads, sitting next to a default nobody intended to keep.
- Is it better to merge the layers in the deployment tooling or inside the process at start-up?Merging in the tooling makes the resolved set an artefact you can render, review and diff before anything runs, and it keeps the layering rules in one place rather than in every workload. Merging inside the process keeps the supplied input tiny and works when nothing in the delivery path can render values. Either is defensible; what is not is having both, in a precedence order nobody has written down.
- What should happen when the supplied value set contains a key the artifact does not recognise?Log it and carry on, rather than refusing to start. An unknown key is usually a value for a version you are rolling towards or away from, or a typo; refusing to start on it makes staged rollouts fragile. Log the key name so a typo is discoverable, and rely on the required-key check for the failure that actually matters, which is a key the artifact needs and nobody supplied.
- Why should a missing stage name be fatal rather than defaulting to the lowest environment?Because a default hides the one case you care about. If an unsupplied stage name resolves to a lower environment's set, a production deployment that lost its stage value comes up healthy, passes its checks, and quietly reads and writes another environment's dependencies. A hard failure turns that into a deployment that never took traffic.
saying these in an interview costs you the question
- Expects the artifact to detect its own environment
- Has an overlay replace the whole document instead of per-key
- Defaults an unsupplied stage name to a lower environment
- Substitutes an empty value for a key nobody supplied
- Keeps two precedence orders and no written rule
- Defers a missing required value to the first request that needs it