Search code examples
azurearmazure-logic-appsazure-bicepazure-workflow-automation

Workflow and API connection provisioning for Standard logic app via Bicep templates/scripts


I'm trying to provision a workflow and an API connection for my Standard Logic app.

This is my logic app bicep script.

resource logicAppResource 'Microsoft.Web/sites@2023-01-01' = {
  name: logicAppName
  location: 'South India'
  kind: 'functionapp,workflowapp'
  identity: {
    type: 'SystemAssigned'
  }
  properties: {
    siteConfig: {
      appSettings: [
        {
          name: 'FUNCTIONS_EXTENSION_VERSION'
          value: '~4'
        }
        {
          name: 'FUNCTIONS_WORKER_RUNTIME'
          value: 'node'
        }
        {
          name: 'WEBSITE_NODE_DEFAULT_VERSION'
          value: '~18'
        }
        {
          name: 'AzureWebJobsStorage'
          value: storageConnectionString
        }
        {
          name: 'WEBSITE_CONTENTAZUREFILECONNECTIONSTRING'
          value: storageConnectionString
        }
        {
          name: 'WEBSITE_CONTENTSHARE'
          value: toLower(logicAppName)
        }
        {
          name: 'AzureFunctionsJobHost__extensionBundle__id'
          value: 'Microsoft.Azure.Functions.ExtensionBundle.Workflows'
        }
        {
          name: 'AzureFunctionsJobHost__extensionBundle__version'
          value: '[1.*, 2.0.0)'
        }
        {
          name: 'APP_KIND'
          value: 'workflowApp'
        }
      ]
    }
    enabled: true
    hostNameSslStates: [
      {
        name: '${logicAppName}.azurewebsites.net'
        sslState: 'Disabled'
        hostType: 'Standard'
      }
      {
        name: '${logicAppName}.scm.azurewebsites.net'
        sslState: 'Disabled'
        hostType: 'Repository'
      }
    ]
    serverFarmId: logicAppServicePaln.id
    reserved: false
    isXenon: false
    hyperV: false
    vnetRouteAllEnabled: true
    vnetImagePullEnabled: false
    vnetContentShareEnabled: false
    // siteConfig: {
    //   numberOfWorkers: 1
    //   acrUseManagedIdentityCreds: false
    //   alwaysOn: false
    //   http20Enabled: false
    //   functionAppScaleLimit: 0
    //   minimumElasticInstanceCount: 1
    // }
    scmSiteAlsoStopped: false
    clientAffinityEnabled: false
    clientCertEnabled: false
    clientCertMode: 'Required'
    hostNamesDisabled: false
    customDomainVerificationId: '0182BAC7C537A4874AED7705B0D4D788E2909F91FBE82947CB8133FDBDD204EA'
    containerSize: 1536
    dailyMemoryTimeQuota: 0
    httpsOnly: true
    redundancyMode: 'None'
    publicNetworkAccess: 'Enabled'
    storageAccountRequired: false
    virtualNetworkSubnetId: '${vnetResourceLogicApp.id}/subnets/${subnetResource.name}'
    keyVaultReferenceIdentity: 'SystemAssigned'
  }
}

But when I try to add workflow

resource logicApp 'Microsoft.Logic/workflows@2019-05-01' = {
  name: logicAppName
  location: resourceGroupLocation
  properties: {
    state: 'Enabled'
    definition: {
      '$schema': 'https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#'
      actions: {
        HTTP: {
          inputs: {
            method: 'GET'
            uri: 'https://ifconfig.me'
          }
          runAfter: {}
          runtimeConfiguration: {
            contentTransfer: {
              transferMode: 'Chunked'
            }
          }
          type: 'Http'
        }
      }
      contentVersion: '1.0.0.0'
      outputs: {}
      triggers: {
        When_a_HTTP_request_is_received: {
          kind: 'Http'
          type: 'Request'
        }
      }
    }
  }
}

It creates a new logic app with the consumption plan. without creating the workflow inside the standered logic app.

logic app code view

Then I tried to manually implement the workflow and tried to get the code but the kind: 'Stateful' propery wont fit in the bicep template.

Also with the API connections, but the API connections create inside the resource group, but couldnot add to the workflow.

connections inside workflow API connection Bicep

resource sqlServerAPIConnection 'Microsoft.Web/connections@2016-06-01' = {
  name: sqlServerAPIConnectionName
  location: resourceGroupLocation
  properties: {
    api: {
      name: sqlServerAPIConnectionName
      type: 'Microsoft.Web/locations/managedApis'
      displayName: 'SQL SERVER'
      brandColor: '#f2f2f2'
      description: 'Connect to SQL Server'
      iconUri: 'https://connectoricons-prod.azureedge.net/releases/v1.0.1683/1.0.1683.3685/sql/icon.png'
      id: '/subscriptions/${subscription().subscriptionId}/providers/Microsoft.Web/locations/${resourceGroupLocation}/managedApis/sql'
    }
    parameterValues: {
      database: sqlServerAPIConnectionDbName
      server: sqlServerAPIConnectionServerName
      username: sqlServerAPIConnectionUsername
      password: sqlServerAPIConnectionPassword
      authType: 'sqlAuthentication'
    }

    displayName: 'SQL'
  }
}

Both API connections and Workflows wont get properly deployed in the Standered Logic APP.

I want to deploy the Standard Logic APP's API connection and workflow.

I tried the consumption plan logic app, which perfectly works with this workflow and the API connections.


Solution

  • I found a way to link the API connections for the standard logic app. I wrote a medium article.

    When creating a consumption Logic app, there is a direct Bicep script for API connections. Link.

    I will demonstrate it with a sample SQL API connection

    var resourceGroupLocation = resourceGroup().location
    
    var sqlServerAPIConnectionDbName = 'dbname'
    var sqlServerAPIConnectionServerName = 'test.database.windows.net'
    var sqlServerAPIConnectionUsername = 'admin'
    var sqlServerAPIConnectionPassword = 'password'
    
    resource sqlServerAPIConnection 'Microsoft.Web/connections@2016-06-01' = {
      name: 'sql'
      location: resourceGroupLocation
      kind: 'V2'
      properties: {
        api: {
          name: 'sql'
          type: 'Microsoft.Web/locations/managedApis'
          displayName: 'SQL SERVER'
          brandColor: '#f2f2f2'
          description: 'Connect to SQL Server'
          iconUri: 'https://connectoricons-prod.azureedge.net/releases/v1.0.1683/1.0.1683.3685/sql/icon.png'
          id: '/subscriptions/${subscription().subscriptionId}/providers/Microsoft.Web/locations/${resourceGroupLocation}/managedApis/sql'
        }
        parameterValues: {
          database: sqlServerAPIConnectionDbName
          server: sqlServerAPIConnectionServerName
          username: sqlServerAPIConnectionUsername
          password: sqlServerAPIConnectionPassword
          authType: 'sqlAuthentication'
        }
        
        displayName: 'SQL'
      }
    }
    
    resource MyLAAccessPolicy 'Microsoft.Web/connections/accessPolicies@2016-06-01' = {
      name: '${sqlServerAPIConnection.name}/${logicApp.name}'
      location: resourceGroup().location
      properties: {
        principal: {
          type: 'ActiveDirectory'
          identity: {
            tenantId: subscription().tenantId
            objectId: logicApp.identity.principalId
          }
        }
      }
    }
    
    output sqlConnectionRuntimeUrl string =  sqlServerAPIConnection.properties.connectionRuntimeUrl
    

    Make sure you add that **Kind **property to V2 otherwise access policies won’t assign

    If you have already created that Logic app, you can add the Logic app name and the object ID from the overview page of the Logic app.

    Scroll down to the JSON view and copy the principle ID.

    This will output a **connectionRuntimeUrl **SQL API connection. I'm using Vscode to deploy the Biucep file.

    Regarding the standard logic app, you can execute the same script but won't find API connections inside the workflows. But there is an already deployed API connection from the Bicep.

    Already deployed API connection via Bicep

    API connection won't display in the Logic app connections

    To enable that API connection for the workflow, Navigate to the Storage account created previously when creating the Standard Logic app.

    Go to the file shares section. Click on the file share and browse.

    Navigate to site -> wwwroot. There, you can find a connections.json file.

    Right-click on that file and download. Open that file using the Vs code.

    Otherwise, this JSON view for API connections is in the Connections section of the workflow.

    Now, you have to edit the JSON file.

      "sql": {
                "api": {
                    "id": "/subscriptions/{subscription id}/providers/Microsoft.Web/locations/${resource group location}/managedApis/sql"
                },
                "authentication": {
                    "type": "ManagedServiceIdentity"
                },
                "connection": {
                    "id": "/subscriptions/{subscription id}/resourceGroups/${resource group name}/providers/Microsoft.Web/connections/sql"
                },
                "connectionRuntimeUrl": "{replace with output runtime url}"
            }
        },
    

    Copy this JSON string and replace the values with the correct details. Subscription id, resource group name and resource group location.

    And paste this inside the managedApiConnections section.

    Save the file.

    You can now see the successfully attached API Connection in the Connections section.

    Now, you can directly assign the API connection when adding an action to the workflow.

    If you want to add an SMTP API connection.

    resource smtpAPIConnection 'Microsoft.Web/connections@2016-06-01' = {
      name: 'smtp'
      kind: 'V2'
      location: resourceGroupLocation
      properties: {
        api: {
          name: 'smtp'
          type: 'Microsoft.Web/locations/managedApis'
          displayName: 'SMTP'
          brandColor: '#f2f2f2'
          description: 'Send emails using SMTP'
          iconUri: 'https://connectoricons-prod.azureedge.net/releases/v1.0.1677/1.0.1677.3637/smtp/icon.png'
          id: '/subscriptions/${subscription().subscriptionId}/providers/Microsoft.Web/locations/${resourceGroupLocation}/managedApis/smtp'
        }
        parameterValues: {
          enableSSL: 'true'
          serverAddress: smtpAPIConnectionServerAddress
          userName: smtpAPIConnectionUserName
          port: smtpAPIConnectionPort
          password: smtpAPIConnectionPassword
        }
        displayName: 'SMTP'
      }
    }
    
    resource smtpConnectionAccessPolicy 'Microsoft.Web/connections/accessPolicies@2016-06-01' = {
      name: '${smtpAPIConnection.name}/${logicAppName}'
      location: resourceGroup().location
      properties: {
        principal: {
          type: 'ActiveDirectory'
          identity: {
            tenantId: subscription().tenantId
            objectId: logicAppPrincipleId
          }
        }
      }
    }
    
    output smtpConnectionRuntimeUrl string = smtpAPIConnection.properties.connectionRuntimeUrl
    

    The variables are

    var smtpAPIConnectionServerAddress = 'smtp-relay.com'
    var smtpAPIConnectionUserName = '[email protected]'
    var smtpAPIConnectionPort = '556'
    var smtpAPIConnectionPassword = 'cb4e6xxx7'
    
    var resourceGroupLocation = resourceGroup().location
    
    var logicAppPrincipleId = 'xxxx5-bfx5-4xxxxxx9b603a'
    var logicAppName = 'logicapptest'
    

    This script also returns the connectionRuntimeUrl for SMTP.

     "smtp": {
                "api": {
                    "id": "/subscriptions/{subscription id}/providers/Microsoft.Web/locations/{resource group location}/managedApis/smtp"
                },
                "authentication": {
                    "type": "ManagedServiceIdentity"
                },
                "connection": {
                    "id": "/subscriptions/{subscription id}/resourceGroups/{resource group name}/providers/Microsoft.Web/connections/smtp"
                },
                "connectionRuntimeUrl": "{connection runtime url}"
            }
    

    Copy this JSON string and replace the values with the correct details. Subscription id, resource group name and resource group location.

    And paste this inside the managedApiConnections section.

    Save the JSON file.

    Now, two API connections are exposed to the Logic app's actions.

    Now, you can create workflow actions using the two API connections.

    source