This readme explains how to setup an Azure Logic App (Standard) running in a Docker container. The workflow will contain an XML operation.
The referenced XSLT map wil be defined directly in the source code of the Logic App project. There's no longer a dependency on Azure Integration Accounts.
The information on this page mainly comes from two official Microsoft blogs:
Another advantage is that you can define and run multiple workflows in one and the same Logic App (just like Azure Functions!). Artifacts (like an XSLT mapping) can also be defined once and accessed by all workflows in the Logic App project 💪.
First of all, currently, you can only create Standard Logic Apps through the Azure Portal or VSCode. You need Visual Studio Code for this advanced use-case.
You need the following VSCode Extensions to be installed:
You also need Docker Desktop (or Rancher Desktop) for building and running your container and Postman for sending requests.
Create a new Logic App (Standard) project:
You can choose between a stateful or stateless workflow, it doesn't really matter for this POC.
Continue by manually creating a .csproj
file.
This is necessary for a NuGet-based approach. This part is necessary to run it in a docker container in one of the later steps...
Make sure to target .NET 6 and Azure Functions v4. You can use this code as a boilerplate. Don't forget to align the Workflow name with yours!
If you have the extension installed, you can edit your workflow inside VSCode by right-clicking the workflow.json
file and choosing Open in Designer
:
Create a simple workflow. For e.g. an HTTP POST request where you post an XML in the body (example input) and convert it to HTML using an XSLT map (myMap.xslt):
As you can see in the screenshot above, you place the mapping in the Maps
folder. You can then point to this specific mapping through Name parameter of the XML operation.
When you right-click the workflow.json file, you also have an Overview
option.
Here you can find the Run History and Callback URL.
Be aware that this screen will only be able to fetch information when the project is actually running locally:
First, you need to add your Azure Storage connection string in the local.settings.json
file:
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": ".....connection string here.....",
.
.
.
}
}
After that, start Azurite for emulating the Azure Storage:
Now you have everything to run the project locally:
Make sure Rancher Desktop (or Docker Desktop) is running.
Continue by creating a Dockerfile
in the root folder:
FROM mcr.microsoft.com/azure-functions/dotnet:4-appservice
ENV AzureWebJobsStorage=.....your connection string here.....
ENV AZURE_FUNCTIONS_ENVIRONMENT Development
ENV AzureWebJobsScriptRoot=/home/site/wwwroot
ENV AzureFunctionsJobHost__Logging__Console__IsEnabled=true
ENV FUNCTIONS_V2_COMPATIBILITY_MODE=true
COPY ./bin/release/net6.0/publish/ /home/site/wwwroot
Then build and publish the project with the following two commands:
dotnet build -c release
dotnet publish -c release
Create the container image:
docker build --tag local/workflowcontainer .
Run the container with the following command. This makes the Logic App accessible through localhost:8080
docker run -e WEBSITE_HOSTNAME=localhost -p 8080:80 local/workflowcontainer
Now for the most difficult part. We need to discover the URL for the HTTP trigger. To do that, we first need to get the masterKey to gain access to the Logic App. You can find this key in the Azure Storage Account that you've indicated in the Dockerfile. Go to the Azure Storage Account and navigate to Containers/azure-webjobs-secrets/{id} and open the host.json file:
There, we can find the masterKey:
"masterKey": {
"name": "master",
"value": "l6vZj8J3aLEZzOfTV7SiiP2H2eru96ajlzZNpoXm5WScABAoP1tlEg==",
"encrypted": false
}
-
Copy the value of the masterKey.
-
Open Postman.
-
Create a new POST request for
http://localhost:8080/runtime/webhooks/workflow/api/management/workflows/{your logic app workflow name}/triggers/manual/listCallbackUrl?api-version=2020-05-01-preview&code={masterKey value}
and send it.
The results from the POST contain the URL of the HTTP trigger and the query parameters to add to the URL:
{
"value": "https://localhost:443/api/LAS_Containerized/..................",
"method": "POST",
"basePath": "https://localhost/api/LAS_Containerized/triggers/manual/invoke",
"queries": {
"api-version": "2022-05-01",
"sp": "/triggers/manual/run",
"sv": "1.0",
"sig": "6NkWBwLMukPgn8foQsnvLtDsX7jpLEB-dMprTZ8Be-w"
}
}
You can use that URL value to construct the HTTP trigger that is running in the container. Don't forget to replace the localhost:443 port with the port we configured for the container: 8080.
http://localhost:8080/api/{your logic app workflow name}/triggers/manual/invoke?api-version=2022-05-01-preview&sp={value for sp}&sv={value for sv}&sig={value for sig}