A Workflow consists of a set of steps that are either declarative or imperative in nature. A
resource of a certain type, that maps a desired state to to a handler for that state, is an example of a declarative step, whereas an
action step with a code block, is an example of an imperative step.
A workflow, being a step in its own right, may be used as a step in another workflow.
All steps consist of the following elements:
|properties||literal hash declaring
|iteration||enables multiple invocations of data or code||no|
|data or code||interpreted differently depending on style||no|
declares a set of parameters. Each parameter has a name and optional
A parameter without a lookup expression must denote a variable known to the containing workflow, i.e. a parameter to the workflow itself or a
returns variable from sibling step. When a workflow contains other workflows, each workflow acts as its own closure and nested references are not allowed.
type can be omitted when the parameter maps to an output variable from another step because the type can then be inferred from the output.
A step will have access to the
parameters that it declares. It will not have access to any other variables. The reason for this is that steps may run in a process different from the workflow engine and will be executed with the presumption that the remote process holds no state. A state must be passed to a step in order for it to execute.
Declares the set of named and typed variables that a step will contribute to the workflow.
returns for a
resource step must always reference named attributes of its state. The
type of such output can therefore always be inferred from the corresponding attribute and is hence optional.
alias can be used when it is desirable to give the output variable a different name than the attribute it references.
declares a guard expression that must evaluate to
true in order for the step to participate in the workflow. A guard expression consists of names of guard steps combined using a language specific notation for
not and grouped using parenthesis.
Since guards will impose conditional paths in the workflow, the number of guards must be limited or the validation will become very resource consuming. The current limit is 8 guards per workflow which results in a maximum of in 28 (256) possible paths of execution. More complex workflows can be created using sub-workflows contained in a parent workflow.
A collector can be declared to iterate over
parameters data or literals.
|times||Calls a contained step the number of times given by count||
|each||Calls a contained step once with all elements of a hash or an array||
A collector step will always produce an array of values where each value is the result of calling the contained step.
A stateHandler implements a predefined set of functions (an interface) that performs tasks related to a subject. Lyra currently only defines one such interface, the CRUD, which is implemented by resource handlers and the only reason to write an action, is when there’s a desire to implement a handler for a resource state.
It is expected that Lyra will add additional interfaces in the future.
An action defines an imperative function that performs some task based on its input and provides some output.
A call is a declaration of an invocation of another publicly available remote step. The call’s parameters and returns declarations can be used to map names used locally to names expected and produced by the remote step.
A resource is a declaration of a desired state of some entity external to the workflow. The
<data or code> block is a hash that defines this state. The block is described by an
Type which is defined by a
stateHandler, a step that can perform
delete operations on the state.
When the workflow interacts with Resource steps, it delegates the apply of the step to the CRUD layer which in turn consults the
stateHandler registered for the state’s
Type. The CRUD layer will determine how to use the
stateHandler depending on how the workflow engine was invoked.
A mandatory type name that denotes the resource type.
An optional ID that denotes the external identifier of read-only (unmanaged) resource. The intended use for this is to establish relationships between the infrastructure defined by the workflow and pre-existing infrastructure that the workflow should make no attempt to manage.
A workflow combines a set of steps into a process. The
<data or code> block is code that declares those steps.