Deploying in the Logic Apps Preview Refresh


One of the key scenarios we wanted to improve as a team when building the Logic Apps Preview Refresh was the deployment process. In the original iteration of Logic Apps, we integrated with Azure API Apps v1, which meant that anytime you wanted to integrate with a service like OneDrive or Salesforce, you provisioned an API App in your own subscription to manage that integration. However, the API App didn’t just include a small web job, but required a Gateway, Gateway Host, API App, and API App Host. All of these pieces (bundled with required Zumo token parameters) made deployment scripts complex and unweildy (check out this simple script to include a single custom API in a Logic App - requires over 350 lines script).

The great news - this experience is now 100xs better. I want to walk you through a few of the main points in creating a deployment script for Logic Apps now that we have moved to the preview refresh.

For a good overview of creating Azure Resource Manager deployments, check out this link: https://azure.microsoft.com/en-us/documentation/articles/resource-group-template-deploy/

Deployment Assets

Now to create a Logic App deployment, you only require 3 things:

  1. App Service Plan
  2. Logic App Definition
  3. Connections (if required)

No gateways, no zumo tokens, no having to deal with one-time-only URLs - a much better deployment experience.

Creating Connections

So how do you create connections? What do they look like and what parameters do I need to pass through? The basic deployment template looks like this:

{
  "type": "Microsoft.Web/connections",
  "apiVersion": "2015-08-01-preview",
  "location": "[resourceGroup().location]",
  "name": "{ConnectionName}",
  "properties": {
    "api": {
      "id": "[concat('subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', resourceGroup().location, '/managedApis/{api}')]"
    },
    "displayName": "{DisplayName}",
    "parameterValues": {
      "..."
    }
  }
}
 

Connection Parameters

You can query the Azure Resource Management API to return the parameters needed for any connection in a Logic App. For example, if I want to create a connection for Azure Blob (which I can see in my Logic App definition is calling /apim/azureblob I can do a GET tohttps://management.azure.com/subscriptions/{subscriptionId}/providers/Microsoft.Web/locations/{region}/managedApis/azureblob?api-version=2015-08-01-preview. I personally use the armclient command line tool so I can simply use armclient get to retrieve the connection metadata. I see from the call the following object that contains the parameterValuesI need in my deployment:

... 
"connectionParameters": 
{ ... }

What About OAuth?

Want to know something awesome about the Preview Refresh of Logic Apps? You can create OAuth connections outside the Azure Portal. This allows you to truly automate your deployments - even those deployments that require consent. So how does it work?

  1. Create a connection from a template like above - however there are no parameterValues - just an api object and displayName.
  2. After deployment, make a POST to /Microsoft.Web/connections/{connectionName}/listConsentLinks?api-version=2015-08-01-preview
    • The request body needs to contain some information about your Azure Account (which can all be found from your Bearer token)
    • The response contains a link you can follow to start the consent flow with the specified service

That’s it! You now have created a valid and active OAuth connection your Logic App will begin using. There is one more step if you are using a Microsoft Account (@outlook.com, @live.com) to access Azure: you need to make one final call after authentication to /Microsoft.Web/connections/{connectionName}/confirmConsentCode?api-version=2015-08-01-preview. The request contains the OAuth code to validate your identity.

I won’t go into detail on this post with examples, but that is the flow you could start using if wanted. If interested to learn more, feel free to monitor your network calls via F12 debug tools or Fiddler when creating an OAuth connection in the Logic Apps Designer - you’ll see this exact flow followed with request/response bodies needed.

Creating An FTP To Blob Template

Let’s use this information to see what a full template of a Logic App that will capture all FTP files and publish them to a Blob container. The full template can be found on GitHub here. Here’s a breakdown of the different pieces:

Here’s what the FTP Connection object looks like:

{
  "type": "Microsoft.Web/connections",
  "apiVersion": "2015-08-01-preview",
  "location": "[resourceGroup().location]",
  "name": "[parameters('ftpConnectionName')]",
  "properties": {
    "api": {
      "id": "[concat('subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', resourceGroup().location, '/managedApis/ftp')]"
    },
    "displayName": "[parameters('ftpConnectionName')]",
    "parameterValues": {
      "serverAddress": "[parameters('serverAddress')]",
      "userName": "[parameters('userName')]",
      "password": "[parameters('password')]",
      "serverPort": "[parameters('port')]",
      "isssl": "[variables('$isssl')]",
      "isBinaryTransport": "[variables('$isBinaryTransport')]",
      "disableCertificateValidation": "[variables('$disableCertificateValidation')]"
    }
  }
}

I then have my Logic App definition as created from the Azure Portal (I substituted a few of the values with parameters to make deployment easier), and at the bottom I reference the connections I just created as parameters for the Logic App:

"parameters": {
  "$connections": {
    "value": {
      "azureblob": {
        "connectionId": "[resourceId('Microsoft.Web/connections', parameters('blobConnectionName'))]",
        "connectionName": "[parameters('blobConnectionName')]",
        "id": "[reference(concat('Microsoft.Web/connections/', parameters('blobConnectionName')), '2015-08-01-preview').api.id]"
      },
      "ftp": {
        "connectionId": "[resourceId('Microsoft.Web/connections', parameters('ftpConnectionName'))]",
        "connectionName": "[parameters('ftpConnectionName')]",
        "id": "[reference(concat('Microsoft.Web/connections/', parameters('ftpConnectionName')), '2015-08-01-preview').api.id]"
      }
    }
  }
}

That’s it. The full script (not including the parameters for deployment) is only about 150 lines - and much much cleaner than a previous Logic Apps Deployment.

What’s Next?

I’ll continue to add more blog posts on deployments in the future, including automating OAuth connections, and using the new Connections objects to show how by simply switching out the parameter references to connections you could easily have different versions of a Logic App for different environments (e.g. ‘Dev Environment’ connections, ‘Prod Environment’ connections) - which means upgrading a Logic App from dev to prod can now be as simple as switching out the connection set parameters. So be sure to keep an eye on this blog for updates. Hopefully it’s clear to see how much more useful and powerful this deployment model is for Logic Apps, and feel free to email me or reach out via Twitter for any questions.

 


	

Comments (5)

  1. Manon Pernin says:

    Hi,

    Thanks for this great post !

    I'm actually working on a Logic App deployment, I made some deployment tests with the refresh preview and script the deployment is really easier !

    I'm waiting for further blog posts about automating OAuth connections, so as to integrate with SalesForce.

  2. Anthony Meehan says:

    Hi Jeff,

    I had to modify your sample slightly to get the connection picked up correctly:

    "parameters": {

     "$connections": {

       "value": {

         "azureblob": {

           "connectionId": "[substring(resourceId('Microsoft.Web/connections', parameters('blobConnectionName')),1)]",

           "connectionName": "[parameters('blobConnectionName')]",

           "id": "[substring(reference(concat('Microsoft.Web/connections/', parameters('blobConnectionName')), '2015-08-01-preview').api.id,1)]"

         },

         "ftp": {

           "connectionId": "[substring(resourceId('Microsoft.Web/connections', parameters('ftpConnectionName')),1)]",

           "connectionName": "[parameters('ftpConnectionName')]",

           "id": "[substring(reference(concat('Microsoft.Web/connections/', parameters('ftpConnectionName')), '2015-08-01-preview').api.id,1)]"

         }

       }

     }

    }

    Basically the problem seems is that connectionId and id can't start with a /. I've used substring to chop it off 🙂

    Thanks.

  3. Anthony Meehan says:

    Sorry, ignore my last comment. It was another issue. Got it working now 🙂

  4. Peter Björkmarker says:

    Hi,

    This works great. Thanks. I have a small integration project being setup with a few web apis and then some logic apps to post and pull messages from the azure service bus.

    I just setup CI builds for the Web API which is super simple and done directly in the portal. Running kudo I believe? For the logic apps that is not currenctly possible so I used VSO build for that.

    Should I move over my web api app build to VSO or can I expect support for something similiar for logic apps soon enough? I.e. not having to use VSO at all?

    Love the work you have done here… Saves me a a couple of 1000 hours…

    Thanks!

    Peter

  5. Harish Balakrishnan says:

    Hi,

    Thanks for this post! I was actually working with the LogicApp ARM template, but I assume that though FTP to Blob or verse is available or supported, the support for Box or oneDrive connections as source connection or destination still needs to be manually created. I do not find any documentation on the same. Hoping you would be able to share or suggest how to address the scenario.

    Regards

    H Bala

Skip to main content