Entity Acquisition (Acquire)
In plain terms, acquire answers the question: "What data does this workflow (or step) need before it can run?" Think of it as a shopping list -- you declare what entities you need, and the engine fetches and locks them for you before execution begins.
The acquire clause lets workflows pull additional entities into the execution context beyond the initial seed entities. This is how you expand the data available to your steps -- for example, loading all interfaces for a device, or selecting specific devices by Elasticsearch query.
Where to Use Acquire
Acquire can be defined at two levels:
- Root level -- Acquires entities for the entire workflow, before any steps execute
- Step level -- Acquires entities for a specific step, just before that step executes
Acquire Types
Elastic Query
Select entities using Elasticsearch query syntax against the CMS:
acquire:
- type: elastic
entity: device
query: "facts.netbox_id: *"
assertNotEmpty: true
description: "Select devices that have a NetBox ID"
This acquires devices whose facts.netbox_id field has a value. The engine queries the CMS's Elasticsearch index and adds matching devices to the context.
| Field | Required | Description |
|---|---|---|
type |
Yes | elastic |
entity |
Yes | Entity type to query (device, interface, group) |
query |
Yes | Elasticsearch query string |
assertNotEmpty |
No | Fail if the query returns no results |
limit |
No | Max entities to return |
description |
No | Human-readable explanation |
Expansion
Expand the context from the seed entity. Commonly used to load interfaces for devices:
acquire:
- type: expansion
entity: interface
expandFromSeedEntity: true
description: "Load all interfaces for each device"
| Field | Required | Description |
|---|---|---|
type |
Yes | expansion |
entity |
Yes | Entity type to expand to (interface, device, group) |
expandFromSeedEntity |
Yes | Whether to expand from the seed entity |
assertNotEmpty |
No | Fail if expansion returns no entities |
description |
No | Human-readable explanation |
Context
Reference entities already in the context, optionally filtering them:
| Field | Required | Description |
|---|---|---|
type |
Yes | context |
entity |
Yes | Entity type to filter |
filter |
No | JMESPath filter expression |
Reference
Reference entities acquired by a previous step:
This adds the devices that were referenced in the step labeled discovery_step to the current context.
| Field | Required | Description |
|---|---|---|
type |
Yes | reference |
entity |
Yes | Entity type |
label |
Yes | Label of the step to reference |
Practical Example
A network health check that first acquires devices by query, then expands to include their interfaces:
acquire:
- type: elastic
entity: device
query: "platform.shortName: ios AND connection_state: OK"
assertNotEmpty: true
description: "Select all reachable Cisco IOS devices"
- type: expansion
entity: interface
expandFromSeedEntity: true
description: "Include all interfaces for each device"
Execution Flow
- Root acquire runs during the
RESOURCE_DISCOVERYphase, before any steps execute - For declarative acquire types (
elastic,expansion,context,reference), the engine resolves them directly via the CMS -- no worker involvement - For function-block-level acquire (defined by the FB's
acquire()method), the engine createsACQUIREjobs on the blackboard, which workers execute - The engine fetches and locks the requested entities from the CMS
- Step acquire runs just before the step, expanding the context available to that step
Why acquire is a separate phase
The acquire phase exists to decouple entity selection from execution. This enables the engine to lock all required entities before any step runs, preventing concurrent workflows from creating conflicts. It also allows function blocks to dynamically determine what data they need at runtime, rather than requiring everything to be specified statically in the workflow definition.
See also:
- Context -- How acquired entity data flows into the execution context
- Execution Model -- How acquire fits into the overall execution lifecycle
- Entity Locking -- How acquired entities are locked for transactional safety
- Implementing
acquire()(Worker SDK) -- How to implement theacquire()method in Python function blocks