Logic apps’ Json code
Behind the Logic Apps designer, there is a Json based source code. Basically, the logic app trigger and all the actions included in the workflow are defined in this file. If you have already checked the “Code View” tab of the Logic Apps designer in the Azure portal, you might have noticed that it also contains other properties such as:
You may have noticed the “triggers” property, which let us think we can have multiple triggers. In fact, yes we can. However it’s only supported by the code definition view, not visually through the designer. Check Microsoft Schema reference for Logic App definition to get further information : https://docs.microsoft.com/en-Us/azure/logic-apps/logic-apps-workflow-definition-language. This being said, I would personally avoid using multiple triggers as long as this feature is not supported by the designer.
Logic Apps’ designer misleading effects
If you are familiar with the Logic App designer, you probably know how it makes it easy to organize your workflow. However, because it doesn’t support all the logic app features, it might also hide some of the Logic App internal workings. The multiple triggers feature is one of them but there are a few others.
Logic Apps’ Action definition
Before going any further, let us pause and see what a Logic App action definition actually looks like. Most actions have the following template:
But some actions diverge a little from this template. For instance, the action “Scope” doesn’t have the “inputs” property, but an “actions” property which contains the whole list of actions inside the scope. Also, if you have implemented custom Log Analytics tracking, or defined any timeout for your actions, you may have noticed some other properties.
Logic Apps trigger settings
Of course, the first step of the workflow is the trigger. After its execution, all the subsequent actions will start. Those are all the actions which :
- aren’t inside a Scope
- have the runAfter property set to empty
So you can have multiple actions executing right after the trigger. You can get this behavior by using the “parallel branch” feature of the designer:
Also, if you click onto the ellipsis button in the top right corner of the trigger box, you will notice that the “configure run after” option is disabled.
This is perfectly handled by the designer.
Logic Apps action settings
Each logic app action is executed only if all the actions inside the runAfter property are completed with the expected result. If you take a look at the sample given above, I actually would like to execute my business scope only when the two initialize variable actions are done. Using the graphical designer to do so is pretty straightforward when you want to make this link through the designer if you do it as soon as you need to. It’s a bit more tricky if you want to change your worklfow’s behavior after the whole process is coded.
For instance, in the picture above, the “New Step” button will add an action linked to both “Initialize variable” actions, resulting in the following workflow :
However, it is a bit more tricky to achieve this result when you have been further in the development of the workflow. In the following case, the “New Step” button will link the “error scope” with the “Initialize TempVar2” action and my business scope won’t be linked to the 2 “Initialize variable” actions as I initially intended.
To solve this problem, you can add a fake step (which you will remove) with the New Step Button, then drag & drop all the actions you want to under the linked step. Or, you can use the Code View tab to manually set the runAfter property.
Also, the Logic Apps run after settings allow us to visually configure the “run after” conditions based on the previous steps execution result : for instance you can specify if a step has to be executed if the previous steps succeeded or failed, or both. Hence, we can build complex workflow scenarios. I also like how the designer makes it easy to configure this property.
The Scope shape
When it comes to managing the “runAfter” property, in some way, the “Scope” action is a bit similar to the main scope :
- the first executed steps have their “runAfter” property set to empty
- the Configure run After option is disabled through the designer
Note that you can have runAfter dependencies only between actions in the same scope level (i.e. same depth).
Also, if you want to have parallel actions in the beginning of the scope, you will have to setup it manually through the “Code view” tab. The next sample has been built thanks to the “Code view” tab. You can see in the business scope, that there is no link between the actions. It means that they will both run as parallel.
If you have actions which will follow them inside this scope, the designer won’t show it properly. It will support it, but won’t show it because of the 2 runAfter conditions. As Microsoft teams are working on all Azure services, I believe this will be fixed in a next releases in a not too distant future. Note that the condition, the loop and the do/until actions have a similar behavior.
Organize your actions
Before finalizing this post, I want to share my experience with the runAfter property. Because the Logic App processing is different from a traditional code processing, having too many runAfter property set to anything else than “Succeed” might be confusing. It can be difficult to have a global view of the workflow and also difficult to manage different cases. For instance, if you have an error during the process, this is not handled like a try/catch scope you can have inside an Azure function: the process will try to find any action that is configured to run after the current action failure. A common mistake is to handle errors with the runAfter property but without a “Terminate” action:
In the given process, the first action ends with the “failed” state :
- then, next action is executed to send an email to an administrator
- the next action is only executed if the send email is skipped, which basically means that it had no error in the first step : this could be an error handling behavior, however, it can be complicated to handle it properly. For instance, If you look in depth at the whole process described in the picture, you can find the same pattern for the last 3 actions.
The last action is executed because we have an error in the first action and the previous action is skipped. Obviously, it doesn’t look like the result we were expecting. My advice is, if you have to stop a process after a failed action, then just stop the workflow with a “Terminate” shape. Also, because i wouldn’t add an error handling pattern after each action, i would advise to use scope shapes to group actions which can execute together, without requiring a complex runAfter configuration. In the sample below “Process File” and “Call API” are 2 scopes containing some actions.
You also can read my post about error handling within logic apps : https://www.middleway.eu/error-handling-within-azure-logic-apps/