One of the most irritating moments of using Azure Logic Apps is writing a HUMONGOUS JSON object that is wrapped by an ARM template. The nature of this Logic App instance inevitably requires us to mix both ARM template expressions and Workflow Definition Language (WDL) expressions. At the time of this writing, as there is no local validation tool around those two, we never know, if the Logic App instance is correctly deployed or not, until it is deployed and run. In this post, we are going to discuss how to deal with parameters between Logic Apps and ARM templates, especially focusing on string concatenation.
Here is a simple user story:
- As a site moderator of SharePointOnline,
- I want to receive a notification email when a file is uploaded or updated,
- So that I can delete the file or leave it.
Defining Logic App
Based on the user story, the graphical representation of a Logic App instance might look like:
- For every 3 minutes, the trigger checks the designated folder whether there is a new file uploaded or existing file has been modified.
- If there is a new file or modified file, send an email notification to the designated moderator through a webhook action.
- In the email, the moderator can choose an option to delete the file or not.
- Based on the option that the moderator has chosen, either the file deletion action or no action is taken.
- If there is an error while deleting the file, the error will be captured.
The complete definition and its ARM template wrapper used for this scenario can be found here.
Let’s have a look at more details.
This workflow is triggered by a scheduled event that looks at a folder in SharePointOnline. The trigger part might look like:
Looks good, right? Nah, it’s actually not. Both
folderId value are hard-coded. Well, at least the Logic App instance has hard-coded both values, which is not desirable, from automation point of view. Instead, those values should be parametrised for future change. Hence, we define parameters within the
parameter section of ARM template like:
And this parameter value is called within the Logic App definition like:
This is deployed without an error. Looks all good, right? Well, let’s see the picture:
The site address field is not showing the actual value. That’s fine, as long as we can run the workflow. When we run the workflow, now we see what has happened:
What we replaced the hard-coded value with
parameters('spoSiteName') was not recognised within the workflow definition. What the…?
Parameters in ARM Template Expressions and WDL Expressions
The issue is simple. Both ARM template and WDL have the same
parameters object. We defined the parameter value in the one of ARM template, but workflow seeks for it within its workflow definition. We now know what the problem is and we also know how to sort this out – 1) use
parameters in workflow definition, or 2) pass the
parameters value from ARM template to workflow definition. Let’s try the first one.
Defining Value in Workflow Definition Parameters
In ARM template, there is only one place where we define
parameters, in most cases. However, when the ARM template comes with Logic Apps, it brings about two more
parameters fields within ARM template. Let’s see the code snippet:
Under the Logic App resource definition, there is the
parameters field for connectors. There is another place under the Logic App workflow definition. We can use both places like:
Wait, it still confuses the reference of
parameters. That’s not the right way because the parameter value is a mixture of template expressions and WDL expressions. How about we only use template expressions and replace WDL expressions with template functions? Let’s try again:
This time, the parameter value under the Logic App resource definition uses template expressions with square brackets and functions. As we can see, the existing WDL function of
encodeURIComponent() has been replaced with template function of
Deployment is successful. But something strange has happened onto the trigger. It doesn’t show the endpoint.
And running the workflow is…
Something weird. It’s not fired! But the log says it points the correct endpoint. WHAAAAT?
Passing Value from ARM Template to Workflow Definition – Direct Way
parameters section within the Logic App resource or definitions is probably not the correct place. Let’s take that out and apply the
parameters value directly from ARM template to workflow definition like:
Then its deployed result might look like:
Now the endpoint has come back! Looks a little bit ugly, though. But that’s fine as long as it works. Let’s run the workflow again.
Yay! It’s running now! So, it seems that mixing two parameters from different sections is not a good idea. Instead, just use the ARM template expressions inside the Logic App definition when the same situation comes. But, there is still a potential issue. As we can see the picture above, the value is URL encoded, which we possibly make mistake if we change the value manually. How can we keep the same experience as what we write the Logic App definition?
Passing Value from ARM Template to Workflow Definition – Indirect Way
There might be another approach. Basically what we are facing is to handle string values in different places. What about parsing WDL expression as a string value within the ARM template expressions? Let’s change the ARM template again. We are not going to use the
parameter object in the Logic App resource definition nor workflow definition. Instead, we are going to use the
parameters object and
variables object in ARM template.
We notice that, in the
variables object, we use string concatenation function that ARM template provides and all WDL expressions and functions such as
encodeURIComponent() function and single quote escaping. This is the final deployment result.
Instead of URL encoded value, we got the human readable value! Actually, in the deployed code side it looks like:
The workflow definition has the original value, even though we parametrised it, which is much nicer. Finally we expect the running result like this:
So far we have sorted out how we could mix ARM template functions and Logic App’s WDL functions, especially around those conflicting
parameters objects. I’m pretty sure this needs to be done in a better way, but until Azure provides a solution, we should probably stick with this approach to avoid string concatenation issues like this.