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

Top comments (0)

🌚 Life is too short to browse without dark mode