Introduction
Camunda is an Open Source Business Process Management Platform that can be used to automate Business Processes for a wide range of industries. With its intuitive Process Modeler Tool and excellent documentation, Camunda has become the go-to solution if you have a need to automate Business Processes using open source technologies. .
As a Solution Provider , one recurring scenario that we keep encountering when implementing Business Process, one recurring scenario that we keep encountering when implementing Business Process Automation solutions for our clients is that of Dynamic Tasks. The scenario is quite simple - the number of User Tasks is not known at the time of Process Definition creation.
Sample Scenarios
A software product release pipeline could be modeled as a Process in Camunda where a “Checker” evaluates if the product behaves as expected in a lower environment and promotes the product to the next higher environment. The number of such environments itself will be dynamic between Organizations or even between Departments within the same Organization.
A document approval chain could consist of different stages, where each stage has multiple approvers evaluating the document in sequence or parallel. This is the example that we will be considering in this article. The picture below illustrates various stages and approvers in the approval flow. A key point to note is that a document is considered as approved only if it is approved by all parties. Even if a single party in the chain rejects the document, the flow is aborted and the document is considered as rejected.

Solution
We make use of 3 important Camunda constructs to achieve this -
Multi-instance Activities
A multi-instance is a regular activity that has extra properties defined, which will cause the activity to be executed multiple times at runtime. It allows for multiple executions of a certain step or even a complete subprocess for each item in a given collection. The execution can be configured to happen sequentially or in parallel.
Message Events
Message Throwing Event
A process can contain intermediate message throw events to model the publication of a message to an external system like a Kafka topic or even to other activities within the same process.
Intermediate Message Catching Event
When a token arrives at the message intermediate catching event, the execution waits there until a message with the proper name arrives.
Call Activity
A Call Activity is used to trigger the start of a new process instance from the original process, thereby creating parallel child executions within a regular process. The main process instance waits until the subprocess has completely ended, and continues the original process afterwards.The main use case for the call activity is to have a reusable process definition that can be called from multiple other process definitions.
Finally, the number of stages and approvers in each stage is passed as a JSON process variable called “stages” with the following structure -
[ { "type": "PARALLEL", "approvers": [
"David","Roger", "Nick","Richard"] }, { "type":
"SEQUENCE", "approvers": [ "Jim", "Robert", "John"] }
]
Using the above concepts from Camunda, we model the process as shown below -

Process Walk through
1. The entry point for the document approval flow is the Process called “Main”. This is started by passing in the “stages” JSON described earlier, as a process variable
2. Inside the Main process, we have a multi-instance embedded sub-process called “Loop Through Stages” - whose job, as you guessed it, is to loop through the “stages” process variable. The looping expression is as shown below

3. For each stage, the subprocess makes a decision as to
whether it is a SEQUENCE
or a
PARALLEL
stage and accordingly branches to
the Evaluate Document in Sequence
or
Evaluate Document In Parallel
call
activity. See the expression below for one of the
branches -

4. Evaluate Document in Sequence
and
Evaluate Document In Parallel
are both
multi-instance Call Activity that loop through the
approvers in each stage and call the reusable
stand-alone process called Evaluate Document. See the
loop expression and called activity configuration below
-

5. Finally, the actual manual review by an approver is modeled as a standalone callable process. This has a couple of advantages -
(a) The actual manual review process need not be
repeated in each of the
Evaluate Document in Sequence
or
Evaluate Document in Parallel
activity as
an embedded sub-process.
(b) Changes to the actual manual review process like adding ad-hoc approvers or reminders (both of which will be covered in a subsequent article) will be restricted to this standalone process.
6. In the Evaluate_Document process, when a document is rejected, a Message is published using the Message Throwing Event. Since this message is primarily intented to be processed by instances of the Main Process, we use the Process Engine API to publish the message. The name and expression to throw the message is shown below -

7. The above message is caught as a Message Catching Boundary Event. This is modeled as an interruption event - when the “Document Rejected” message is caught, the main process is taken to the end state. This ensures that any child processes and Tasks that are created as part of the approval chain are immediately destroyed upon rejection.
Conclusion
In conclusion, in this article we saw how to make use of Camunda / BPMN constructs like Multi-instance activities, Messages and Call Activities to implement processes that involve a dynamic number of User Tasks.