Giuliano De Luca | Blog | delucagiuliano.com

Azure DevOps is increasingly used to automate the release of solutions to the cloud. In this context, I would like to report my recent experience by developing continuous integration and delivery for logic apps, hoping that it will be useful to someone else.

Logic Apps is one of my favorite resource on Azure because is incredible fast, intuitive and easy to use. My personal opinion is that, Logic Apps works great in those scenarios where a workflow is needed and when more, in general, the business logic is not so complex, in fact, in this use case I prefer to use an Azure Function instead of Logic Apps for performance reason. you can find more info about Logic Apps here

ARM Template

Let’s start from what we need in order to deploy an existing or created Azure resource and more specifically in our case a Logic App. Basically, we need a file where all configurations for our Azure resource are saved, I’m talking about Azure Resource Manager Template or better known as ARM Template. This is nothing more than a JSON file where various information is contained and in the case of Logic App we will have something like that:

This Logic App is an HTTP trigger that reads an Azure Key Vault value, put this value in the body of an email and send the email, that’s it. I decided to include a reference to an Azure Key Vault Secret to this article because I think it should be always used in any kind of architecture, I use always this resource in my solutions to increase security. In this regard, in order to read the secret value and transfer it to the Logic App, it is necessary to enable Azure Resource Manager for template deployment in the access policy of the key vault, obviously access to the Logic App must be inhibited to those who develop it.

Giuliano De Luca | Blog | delucagiuliano.com

On top we have all parameters, then some info like, which trigger is used, name of the Logic App, the location which in my opinion should be parameterized in this way every time I can decide in which region deploy my Logic App, then the business logic and at the bottom every connection related to the connectors used. Very important in the connections section is the id, in my case is:

"id": "/subscriptions/3d0b8544-e3c0-42f5-bffd-7577fc2dc70e/providers/Microsoft.Web/locations/westeurope/managedApis/outlook"

where the guid identify the subscription id of Azure and the location, my goal is to have a template that I can reuse always and in any case, so that means for every Azure subscription. In order to do that the id should be built as below:

"id": "[concat(subscription().id, '/providers/Microsoft.Web/locations/', resourceGroup().location, '/managedApis/', 'outlook')]"

in doing so the id will be taken dynamically from the Azure subscription where I am logged in. However that’s not all, in fact, there is another JSON file that contains the parameters used in the template, as best practice we should have a parameter JSON file for every environment, in order to differentiate the values. Here how looks like mine:

There are 4 parameters, logic app name, logic app location, the URL connection for the outlook connector and the URL of my secret in the Key Vault.

Azure DevOps

We are now ready to configure continuous integration and delivery on Azure DevOps. My repository contains only JSON files, more specifically the main JSON file with the Logic App’s business logic and additional files to handle parameters in different environments, let’s go to the pipelines now. All I need to do, is set up the release pipeline because basically I have nothing to build, in fact, I have already the ARM template ready to deploy in Azure. Below my simple release pipeline:

Giuliano De Luca | Blog | delucagiuliano.com

and here my super complex release pipeline tasks:

Giuliano De Luca | Blog | delucagiuliano.com Giuliano De Luca | Blog | delucagiuliano.com

Recapping what I have done in the configuration, I added an Azure Resource Group Deployment and I configured the following parameters:

  • Display name
  • Azure subscription (Where to deploy the Logic App)
  • Action
  • Resource group (Where is contained the Logic App)
  • Location
  • Template location
  • Template
  • Template parameters
  • Deployment mode (Incremental deployment)

Now taking back to the URL of before:

"id": "[concat(subscription().id, '/providers/Microsoft.Web/locations/', parameters('LogicAppLocation'), '/managedApis/', 'outlook')]"

The reason why I replaced hardcoded values with dynamic values is easy to figure out, in fact, directly from the Azure Resource Group Deployment task I can define the subscription Id, resource group, location, and all these values are read in the JSON during the deploy, but in this case I prefer to use the existing paramater in order to freely decide where to deploy the logic app.

Source code of the solution on my GitHub repo: https://github.com/giuleon/LogicApps-DevOps

Video: