DEV Community

Leonard Soetedjo
Leonard Soetedjo

Posted on

Automating Azure APIM configuration based on Logic App (standard) workflows' callback URLs

Continuing from my research to retrieve Logic App (standard) workflow callback URL, my next step was to automatically configure the Azure API Management in bicep.

My plan is to retrieve list of workflows for a particular Logic App (standard), and then iteratively configure APIM to add the backend endpoints. I had thought that it's an easy case, but it's not.

The resulting json from listcallbackUrl() is as follows (sample from Microsoft website):

{
  "value": "https://prod-03.westus.logic.azure.com/workflows/d4690301f3b340de9330256bb2e83974/triggers/requestTrigger/paths/invoke?api-version=2016-06-01&se=2018-04-19T16%3A00%3A00.0000000Z&sp=%2Ftriggers%2FrequestTrigger%2Frun&sv=1.0&sig=JXbHjs3qzLPDyk-IM_VzsN-WL_mNql3v_uWbBbKgtVk",
  "method": "POST",
  "basePath": "https://prod-03.westus.logic.azure.com/workflows/d4690301f3b340de9330256bb2e83974",
  "queries": {
    "api-version": "2016-06-01",
    "se": "2018-04-19T16:00:00.0000000Z",
    "sp": "//*",
    "sv": "1.0",
    "sig": "JXbHjs3qzLPDyk-IM_VzsN-WL_mNql3v_uWbBbKgtVk"
  }
}
Enter fullscreen mode Exit fullscreen mode

My requirements need me to populate APIM's set-backend-service and rewrite-uri. With the above json, a user-defined function is required. And alas, as of now it's not possible in bicep :(

After further research and testing, in the end this is what I came up with:

  1. Call a new module from the main bicep file by passing an array of logic app
module cbUrl 'module_cburl.bicep' = [for (item, i) in apiOperations: {
  name: 'url${i}'
  params: {
    logicAppId: resourceId(logicAppName)
    workflows: item
  }
}]
Enter fullscreen mode Exit fullscreen mode
  1. Create the module that just call listCallbackUrl() and provide the output with my custom format
param logicAppId string
param workflows string

var url = listCallbackURL('${logicAppId}/hostruntime/runtime/webhooks/workflow/api/management/workflows/${workflows}/triggers/manual', '2022-03-01')
var apiVersion = url.queries['api-version']

output url object = {
  basePath: url.basePath
  queries: '?api-version=${uriComponent(apiVersion)}&sv=${uriComponent(url.queries.sv)}&sp=${uriComponent(url.queries.sp)}&sig=${uriComponent(url.queries.sig)}'
}

Enter fullscreen mode Exit fullscreen mode
  1. Use the array of result into API Management policy, iterating it with the same apiOperations variable.
resource apiPolicies 'Microsoft.ApiManagement/service/apis/operations/policies@2021-08-01' = [for (item, i) in apiOperations: {
  name: '${apimSvcRef.name}/${apiName}/${item}/policy'
  properties: {
    value: '<policies>\r\n  <inbound>\r\n    <base />\r\n    <set-backend-service base-url="${cbUrl[i].outputs.url.basePath}" />\r\n    <rewrite-uri template="${cbUrl[i].outputs.url.queries}" />\r\n  </inbound>\r\n  <backend>\r\n    <base />\r\n  </backend>\r\n  <outbound>\r\n    <base />\r\n  </outbound>\r\n  <on-error>\r\n    <base />\r\n  </on-error>\r\n</policies>'
    format: 'xml'
  }
}]
Enter fullscreen mode Exit fullscreen mode

Oldest comments (2)

Collapse
 
mylopeda profile image
Jakob Carlsson

If I understand your writing correctly I need to have the workflow deployed for this to work? You didn't find a way to use a Logic App global key to call your workflows? So I would have to deploy my bicep that builds up the Logic App, then deploy my workflows and after that run some more bicep that creates the API in APIM?

I have been looking for a while now for a way to automate the adding of sig to the workflow URL. I found the other parts quickly but never found a way to add the sig to the URL without having the workflow deployed.

Collapse
 
leonards profile image
Leonard Soetedjo

Sorry for the late reply. Yes, I did deploy the workflows first and setting the APIM as last because only when the workflow is deployed will the Logic App workflow's endpoint url be created.