Welcome again to another Logic Apps Best practices, Tips, and Tricks. In my previous blog posts, I talked about some of the most essential best practices you should have while working with the Azure Logic App:
And some tips and tricks:
- #4 Using Scopes
- #5 Delete comments
- #6 Error handling configure run after settings
- #7 Learn from failures
- #8 Expressions nightmare
- #9 Control your connectors (API connections)
- #10 Fix connectors (or API connections)
- #11 Connectors naming convention
- #12 Choose your developer tools properly
- #13 Logic App (Standard) vs (Consumption)
- #14 Implement good governance policies
- #15 get the error message
- #16 roll back to a previous version of an Azure Logic App Consumption
- #17 using other HTTP Methods then POST
- #18 Foreach Parallelism
- #19 Protect your Logic Apps (Part I) – Using API Management to expose the Logic App and Implement IP Addressing Restriction
- #19 Protect your Logic Apps (Part II) – Secure data in the run history by using obfuscation
In my last blog post, I discussed securing our Logic App. I may return to this topic in the future, but for now, let’s get back once again to developer tricks and tips, and this time to address something that I’m always considering using on my solutions: How to access runtime settings like the Subscription Id or the Resource Group.
Kent Weare did a magnificent blog post about accessing runtime settings in Logic App Standard. I will address in more detail this in my following tips Best practices, Tips and Tricks but for now, you can read more about it here: Programmatically Accessing App Settings from Logic Apps Expressions. In this post, I will address this same topic but focus on Logic App Consumption because these settings and how we can access them differ from Standard to Consumption
Accessing Runtime Settings – Logic App Consumption
When we think about accessing runtime settings in Logic App being Consumption or Standard, our first starting point will be the workflow function. This function will return all the details about the workflow itself during run time, but is it enough?
Let’s take a sample from a previous Best practices, Tips and Tricks: Logic App Best practices, Tips, and Tricks: #15 get the error message. If you remember, there to get a friendly error message from our Logic App, we had the need to pass four values to our Azure Function:
- Subscription Id
- Resource Group
- Logic App name
- and the run id
Of course, with the exception of the run id, which we always need to grab from the runtime, we can always use Logic App parameters to store this information, but I always question why should I need to do this.
So the main questions here are: Can I get these values in runtime? and if yes, how?
Luckily for us, yes we can! But – there is always a but! – depending on your scenario you may need to use different strategies.
Accessing Runtime Settings in Logic App where the trigger is not an HTTP request
If our Logic App uses a trigger that is not an HTTP request like for example a Recurrence trigger then you can grab all the information that you need from the workflow function. This is a sample of the result we should expect:
{ "id": "/subscriptions/XXXXXX/resourceGroups/RG-SASP-LA-POC/providers/Microsoft.Logic/workflows/LA-Accessing-Runtime-Settings-WorkflowOnly-POC", "name": "LA-Accessing-Runtime-Settings-WorkflowOnly-POC", "type": "Microsoft.Logic/workflows", "location": "westeurope", "run": { "id": "/subscriptions/XXXXXX/resourceGroups/RG-SASP-LA-POC/providers/Microsoft.Logic/workflows/LA-Accessing-Runtime-Settings-WorkflowOnly-POC/runs/08585274356988293067892122142CU20", "name": "08585274356988293067892122142CU20", "type": "Microsoft.Logic/workflows/runs" } }
As you see on the JSON result we have all the information we need but – there is always a but! – you need to parse certain information like the Subscription Id and the Resource Group. A simple solution for having all of this information in a simple way to be consumed is for example use a Logic App Compose action:
- On our Logic App Consumption, add a new action by clicking on the + New Step button.
- On the Choose an operation panel, search for Compose and select Data Operations -> Compose action
- On the Compose action we are going to create a JSON message with the following values:
- LARunId: workflow()[‘run’][‘name’]
- Location: workflow()[‘location’]
- LogicAppName: workflow()[‘name’]
- ResourceGroup: split(workflow()[‘id’],’/’)[4] – we are parsing the id parameter of the workflow function to get the resource group
- SubscriptionId: split(workflow()[‘id’],’/’)[2] – we are parsing the id parameter of the workflow function to get the subscription id
You can copy and paste these configurations:
{ "LARunId": "@{workflow()['run']['name']}", "Location": "@{workflow()['location']}", "LogicAppName": "@{workflow()['name']}", "ResourceGroup": "@{split(workflow()['id'],'/')[4]}", "SubscriptionId": "@{split(workflow()['id'],'/')[2]}" }
The result will be:
Accessing Runtime Settings in Logic App where the trigger is an HTTP request
You may be questioning yourself, why I separate non-HTTP triggers from HTTP request triggers. Shouldn’t be the same? Maybe yes, maybe not, Maybe for security reasons, Microsoft decided to implement a different behavior, I honestly don’t know. But the reality is that when we have an HTTP request trigger the subscription id, and the resource group are surprised by the workflow() function result. This is a sample of the result we should expect from the workflow() function when you use an HTTP Request trigger:
{ "id": "/workflows/491aaa72a80d43268dc5662890c4ad56", "name": "LA-Accessing-Runtime-Settings-POC", "type": "Microsoft.Logic/workflows", "location": "westeurope", "run": { "id": "/workflows/491aaa72a80d43268dc5662890c4ad56/runs/08585274572372200410167717616CU168", "name": "08585274572372200410167717616CU168", "type": "Microsoft.Logic/workflows/runs" } }
As you can see there is less information available. Now the main question here is: Can we get that information using another function or in some alternative way?
Unfortunately, we cannot use another function to retrieve this information (Subscription Id and Resource Group) in runtime, but luckily we can implement a simple strategy (or workaround if you prefer to call it that way) to retrieve this information by calling a simple child Logic App. To do that you need to:
- Create a simple Logic App using the HTTP Request-Response template
- And on the Response action we are going to create a JSON Response message with the following values:
- LARunId: triggerOutputs()[‘headers’][‘x-ms-workflow-run-id’]
- Location: triggerOutputs()[‘headers’][‘x-ms-execution-location’]
- LogicAppName: triggerOutputs()[‘headers’][‘x-ms-workflow-name’]
- ResourceGroup: triggerOutputs()[‘headers’][‘x-ms-workflow-resourcegroup-name’]
- SubscriptionId: triggerOutputs()[‘headers’][‘x-ms-workflow-subscription-id’]
- This startegy allow us to retrieve the same values, including the missing one: Subscription Id and Resource Group
- The reason why we can archive this is that when we call the child Logic App by using the Logic App connector or the HTTP Connector by default it will add all of this information in the headers. Here is an exampl
{ "headers": { "Accept-Language": "en-US", "User-Agent": "azure-logic-apps/1.0,(workflow 491aaa72a80d43268dc5662890c4ad56; version 08585274576634340064)", "x-ms-workflow-id": "491aaa72a80d43268dc5662890c4ad56", "x-ms-workflow-version": "08585274576634340064", "x-ms-workflow-name": "LA-Accessing-Runtime-Settings-POC", "x-ms-workflow-system-id": "/locations/westeurope/scaleunits/prod-190/workflows/491aaa72a80d43268dc5662890c4ad56", "x-ms-workflow-run-id": "08585274576572585047927169524CU171", "x-ms-workflow-run-tracking-id": "22a91b37-d09f-404f-b74a-f27d6eeb1c9b", "x-ms-workflow-operation-name": "LA-BP-Tip-Trick-GetSubsIdAndResourceGroup-Workaround", "x-ms-execution-location": "westeurope", "x-ms-workflow-subscription-id": "XXXXXX", "x-ms-workflow-resourcegroup-name": "RG-SASP-LA-POC", "x-ms-tracking-id": "e22e14e1-2381-4071-ae46-320e690700dc", "x-ms-correlation-id": "e22e14e1-2381-4071-ae46-320e690700dc", "x-ms-client-request-id": "XXXXX", "x-ms-client-tracking-id": "08585274576572585047927169524CU171", "x-ms-action-tracking-id": "7fe24729-fafc-4199-97d0-d1ebccd7c468", "x-ms-activity-vector": "IN.08" } }
Note: Before you go crazy about this information to be pass in the headers for security reasons, you can disable this behaviour and I will go address this in one of my next Best practices, tips and tricks.
So now, my main Logic App is able to use this information:
Stay tuned for the following Logic App Best practices, Tips, and Tricks.