Prevent Concurrent Changes to a Shared Resource
For the complete documentation index, see llms.txt. For a full content snapshot, see llms-full.txt. Append.mdto anykestra.io/docs/*URL for plain Markdown.
Available on:Enterprise EditionCloud
Lock an asset while one execution changes the underlying resource, so other executions can’t change it at the same time.
Two executions that patch the same server, or a patch that runs while an inventory refresh rewrites the server’s metadata, leave the resource and its asset record in an unknown state. An asset lock gives one execution exclusive write access for a limited time. Other executions either wait for the lock or have their writes skipped.
Prerequisites
- A Kestra Enterprise Edition or Cloud instance.
LOCKandUNLOCKpermissions on theASSETresource for the credentials that the lock tasks use. See Connection properties for API-based tasks.- An asset to lock. A lock can only be taken on an asset that exists.
Register the resource as an asset
If the server isn’t an asset yet, register it. This flow declares a VM asset as the output of a log task:
id: register_db_servernamespace: company.infra
tasks: - id: register type: io.kestra.plugin.core.log.Log message: Registering db-prod-01 assets: outputs: - id: vm.db-prod-01 namespace: company.infra type: io.kestra.plugin.ee.assets.VM metadata: provider: aws region: eu-west-1 state: runningAfter one execution, vm.db-prod-01 appears in the Assets list.
Lock the asset around the work
This flow takes the lock, patches the server, records the patch on the asset, and releases the lock:
id: patch_db_servernamespace: company.infra
tasks: - id: acquire_lock type: io.kestra.plugin.kestra.ee.locks.Acquire assetId: vm.db-prod-01 ttl: PT30M retry: type: constant interval: PT1M maxAttempts: 30
- id: patch type: io.kestra.plugin.scripts.shell.Commands taskRunner: type: io.kestra.plugin.core.runner.Process commands: - echo "Patching vm.db-prod-01" - sleep 60 assets: outputs: - id: vm.db-prod-01 type: io.kestra.plugin.ee.assets.VM metadata: last_patched: "{{ execution.startDate }}" patched_by: "{{ execution.id }}"
finally: - id: release_lock type: io.kestra.plugin.kestra.ee.locks.Release assetId: vm.db-prod-01Notice these choices:
ttlcovers the longest expected run of the work, with margin. If the execution stops without releasing the lock, the lock still expires.retrymakesacquire_lockwait. If another owner holds the lock,Acquirefails with HTTP 423, and the retry tries again every minute for up to 30 attempts.- The
patchtask writes the asset while the lock is held. The execution that holds the lock can write, and each write extends the lock. release_lockruns infinally, so the lock is released whether the patch succeeds or fails.Releasedoes nothing if the lock has already expired.
Replace the Shell commands with your real patching task.
See what a competing execution gets
Start patch_db_server twice in a row. The second execution’s acquire_lock task fails with HTTP 423, retries, and takes the lock once the first execution releases it.
Writes that don’t go through Acquire behave differently. This flow refreshes the inventory and writes the same asset without taking a lock:
id: refresh_inventorynamespace: company.infra
tasks: - id: refresh type: io.kestra.plugin.core.log.Log message: Refreshing inventory for vm.db-prod-01 assets: outputs: - id: vm.db-prod-01 type: io.kestra.plugin.ee.assets.VM metadata: state: runningIf it runs while patch_db_server holds the lock, the refresh task ends in WARNING, and its logs explain that the asset is locked. Kestra doesn’t change the asset. To make that case fail the task instead, set assetFailureBehavior: FAIL in the task’s assets block. See Failure behavior.
Lock an asset for a maintenance window
To stop every flow from changing a resource during manual maintenance, lock it as a user:
- Open the asset from the Assets list.
- Open the ⋮ menu, select Lock, choose a duration from 5 minutes to 24 hours or Custom, and confirm.
- When the maintenance is done, open the ⋮ menu and select Unlock.
A user lock blocks writes from every execution, including executions you start yourself. Acquire tasks fail with HTTP 423 until the lock ends.
To script the maintenance window, call the API. This request locks the asset for two hours:
curl -X POST "https://kestra.example.com/api/v1/main/assets/vm.db-prod-01/lock" \ -H "Authorization: Bearer $KESTRA_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{"ttl": "PT2H"}'This request removes the lock, whatever its owner:
curl -X DELETE "https://kestra.example.com/api/v1/main/assets/vm.db-prod-01/lock" \ -H "Authorization: Bearer $KESTRA_API_TOKEN"Removing a lock that an execution holds leaves that execution’s later writes unprotected. Use it to clear a lock that a stopped execution left behind.
Verify the result
- While
patch_db_serverruns, the asset’s Overview tab shows who holds the lock and until when, and the Assets list can be filtered by lock status. - After the run, the asset’s metadata shows
last_patchedandpatched_by, and the Executions tab lists bothregister_db_serverandpatch_db_server. - If
refresh_inventoryran during the patch, its execution ended inWARNING, and the asset’s metadata still has the values frompatch_db_server.
Next steps
Was this page helpful?