skip to content

You changed a project variable in Octopus Deploy, then redeployed an existing release to Production, but the old value was still used. Why, and what are your options?

level: seniorimportance: should knowfreq 42%

answer

  1. the editor shows now, the release shows then
  2. variables are frozen with the process
  3. deliberate, for reproducibility
  4. a targeted refresh action exists
  5. refreshing variables does not refresh steps

basics

~20 s

Octopus Deploy snapshots a project's variables when the release is created, so later edits do not reach existing releases. Either use Update Variables on that release to refresh its variable snapshot, or create a new release.

solid answer

~50 s

This is by design, not a bug. When Octopus creates a release it snapshots the deployment process, the selected package versions **and** the variables — including values pulled in from library variable sets. Redeploying replays that snapshot, so an edit made in the project's variable editor afterwards is invisible to it. You have two options. Use **Update Variables** on the release, which re-snapshots the variables against the project's current values while leaving the deployment process alone; or create a new release, which re-snapshots everything. Prefer a new release when the change is part of shipping something, and Update Variables when you are correcting a value on a release already mid-promotion. Bear in mind that updating variables on a release means the thing you deploy to Production is no longer identical to the thing that passed Test, so re-verify in a lower environment first.

go deeper

for a junior

Remember that a release freezes its variables when it is created, so editing a variable afterwards does not change an existing release. Say that creating a new release is the straightforward fix.

for a middle

Explain what the snapshot covers — project variables plus library variable sets and their scopes — and describe Update Variables as the action that refreshes variables only, leaving the process and package versions alone.

for a senior

Diagnose before fixing: check the variables recorded on the failed deployment against the editor, rule out a scoping or substitution mistake, then choose between Update Variables and a new release knowing the first weakens the tested-equals-shipped guarantee.

for a principal

Own the boundary policy: which configuration lives inside the versioned snapshot for auditability, which is fetched at deploy time so rotation never touches releases, and what evidence the organisation must be able to produce about what was in effect during any given deployment.

## What actually happened Octopus Deploy's release is an immutable snapshot, and the snapshot includes variables. At the moment the release was created, Octopus recorded the project's variables, every library variable set the project includes, and all of their scopes, and stored that copy on the release. Deploying — or redeploying — replays that stored copy. The project's variable editor shows *current* values, which is why the UI looks like the change took effect while the deployment plainly did not use it. This catches people because most CI systems read configuration live at run time. Octopus deliberately does not, for the same reason it pins package versions: a release that passed Test must be re-deployable to Production and produce the same result. If variables were read live, a value edited between the Test deployment and the Production deployment would silently change what shipped, and the audit trail would not show it. ## Confirming the diagnosis Before reaching for a fix, verify it rather than assuming. Every deployment records the variables that were in effect for that run, and the task log shows the value each variable resolved to (sensitive values are masked). If that snapshot shows the old value while the project editor shows the new one, the diagnosis is confirmed. This also rules out the two neighbouring causes: a **scoping** mistake, where the new value exists but is scoped to an environment or role that does not match this deployment, and a **substitution** mistake, where the variable resolved correctly but the file transform that was supposed to write it into configuration never ran on that step. ## The two fixes **Update Variables on the release.** This action re-snapshots the release's variables from the project's current values and its library variable sets. It does *not* re-snapshot the deployment process — the steps stay exactly as they were — and it does not change the package versions. This is the right move when a release is already partway through its lifecycle and you need to correct a value without disturbing what has been tested. **Create a new release.** Everything is re-snapshotted: variables, process, package selection. This is the right move when the variable change is genuinely part of shipping something new, and it is the honest choice most of the time, because it gives you a fresh version number to talk about and an audit record of what changed. There is a real judgment between them. Updating variables on a release breaks the property you were relying on: the release that passed Test is no longer bit-identical in behaviour to the one going to Production. Do it knowingly, and re-deploy to a lower environment afterwards if the value has any behavioural weight. ## What is *not* snapshotted Not everything is frozen. Values a step fetches at deploy time — a secret read from an external secret store by a script or a dedicated step, or a value computed by an earlier step and set as an output variable — are resolved during the deployment, not captured at release creation. Some teams lean on this deliberately: keep genuinely rotating material (credentials, tokens) outside the snapshot so that rotating it does not require touching releases, and keep declarative configuration (hostnames, feature toggles, sizes) inside the snapshot where it is versioned and auditable. That is a good line to be able to draw in an interview. Variable substitution itself happens at deploy time against the snapshot. A configuration file containing a placeholder is transformed as the step runs: ```json { "ConnectionStrings": { "Default": "#{Database.ConnectionString}" } } ``` The `#{...}` syntax is resolved from the release's variable snapshot, with scoping applied for the environment being deployed to — which is exactly how one release produces different configuration in Test and Production without any rebuild. ## Scoping, the adjacent trap Variables are scoped — to environments, target roles, specific machines, steps, channels or tenant tags. When several values of the same name match the current deployment, Octopus picks the most specifically scoped one. If two matches are *equally* specific, the outcome is ambiguous: Octopus will pick one, and you should not rely on which. Treat equally-scoped duplicates as a configuration defect to be removed rather than a precedence rule to be learned. ## The interview point What is being tested is whether you understand that Octopus trades live configuration for reproducibility on purpose. A candidate who says "variables must be read at deploy time, so something is caching" has the model backwards. A strong answer names the snapshot, names Update Variables as the surgical fix, prefers a new release as the default, and flags that re-snapshotting a mid-flight release weakens the guarantee that promotion is supposed to give you.

  • Does Update Variables also pick up changes to the deployment process?
    No. It re-snapshots only the variables, including values from library variable sets the project includes. The steps stay exactly as they were captured at release creation, and the selected package versions are untouched. If the process itself changed, you need a new release — there is no way to graft new steps onto an existing one.
  • How does Octopus decide which value wins when a variable is defined several times with different scopes?
    It matches the scopes against the current deployment — environment, target role, machine, step, channel, tenant tag — and picks the most specifically scoped match. If two matches are equally specific the result is ambiguous and you should not depend on which one wins; remove the duplicate rather than trying to predict the precedence.
  • Which values are deliberately kept outside the snapshot?
    Anything resolved during the deployment: secrets fetched from an external store by a step or script, and output variables set by an earlier step. Teams often put rotating credentials there on purpose, so rotation never requires touching existing releases, while keeping stable declarative configuration inside the snapshot where it is versioned and auditable.
  • Why is re-snapshotting a mid-promotion release something to think twice about?
    Because the release that passed Test is no longer behaviourally identical to the one entering Production, which is the exact property promotion exists to give you. If the value has any behavioural weight, redeploy to a lower environment after updating, or create a new release and promote it normally.

saying these in an interview costs you the question

  • Assumes variables are always read live at deploy time
  • Blames a cache on the Tentacle or the target
  • Thinks Update Variables also refreshes the deployment steps
  • Believes you must rebuild the artifact to change a variable
  • Treats equally scoped duplicate variables as a precedence rule

context