Per-Stack Update Locking: Does Pulumi Queue Concurrent Runs or Fail Immediately?
0 reputation · 22 Jul 2021, 15:33 UTC
0 reputation · 22 Jul 2021, 15:33 UTC
When a stack is being updated, Pulumi’s Cloud backend automatically acquires a per‑stack lock. On self‑managed backends (file, S3, GCS, Azure Blob) this lock is not enforced, so two pulumi up processes can race on the state file. The CLI offers a --parallel flag to control how many resource operations run concurrently, but the interaction between this flag, the lock mechanism, and the backend type is not fully documented.
In practice, an in‑progress run may either return a busy/lock error immediately or queue the second run until the first completes, depending on version and backend. This uncertainty complicates CI pipelines that trigger parallel deployments and can lead to state corruption or wasted retries.
Key constraints include:
--parallel value is derived from the machine’s CPU count and varies by CLI version.Unresolved decisions:
How does the current default --parallel setting affect the likelihood of encountering lock errors during simultaneous updates?
What is the exact sequence of events when a second pulumi up is launched while the first is still running on a self‑managed backend?
34775 reputation · 23 Jul 2021, 01:48 UTC
On a self‑managed backend (file, S3, GCS, Azure Blob) Pulumi does not queue concurrent runs. The second pulumi up will either:
busy/lock error immediately (newer CLI releases), orIn either case the --parallel flag does not coordinate across separate CLI processes; it only throttles resource operations inside a single run.
CI pipelines that launch parallel deployments can suffer from:
Both scenarios are prevented if you either migrate to Pulumi Cloud (which enforces per‑stack locks) or add a CI‑level lock (e.g., a DynamoDB entry, Redis key, or a simple file lock on a shared network filesystem).
Check the CLI version:
pulumi versionRun two pulumi up commands in parallel against the same stack on a self‑managed backend (e.g., a local file store). Use --parallel 1 to isolate resource ops if you want deterministic output.
Observe the exit status of the second run:
0 – it succeeded; check the state file timestamp to see if it overwrote the first run.busy or lock – it failed immediately.If the second run succeeded, run pulumi state list and compare the resource counts to the first run to confirm whether changes were lost.
Repeat the test on Pulumi Cloud to confirm that the second run is queued and the first completes first.
For reliable CI, consider one of the following:
pulumi up.To tailor the recommendation precisely, could you share the exact Pulumi CLI version you are using? The lock‑error semantics changed in the 2024.3 release, so the outcome may differ between 3.45 and 3.48.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.