Office365 connection in Logic App

Using Bash to Deploy a Logic App using an Office365 API Connection

Office365 connection in Logic App

Using Bash to Deploy a Logic App using an Office365 API Connection

Since moving to a self-hosted agent I did not have Powershell available or the bash command to parse JSON, jq. If you have installed Powershell onto your agents then please refer to this earlier post for my solution using Powershell: Using Powershell to Deploy a Logic App using an Office365 API Connection

Otherwise, I spent many hours working out how to accomplish the same with only Bash:

  1. Validate then build the Office365 Connection
  2. "resources": [
        {
          "type": "Microsoft.Web/connections",
          "apiVersion": "2016-06-01",
          "name": "[parameters('name')]",
          "location": "[parameters('locationName')]",
          "tags": "[parameters('tags')]",
          "kind": "V2",
          "properties": {
            "api": {
              "id": "[concat('/subscriptions/',subscription().subscriptionId,'/providers/Microsoft.Web/locations/',parameters('locationName'),'/managedApis/office365')]"
            }
          }
        }
      ],
      "outputs": {
        "office365connectionid": {
          "type": "string",
          "value": "[concat('/subscriptions/',subscription().subscriptionId,'/resourceGroups/',resourceGroup().name,'/providers/',reference(resourceId('Microsoft.Web/connections', parameters('name')),'2018-07-01-preview', 'full').resourceId)]"
        },
        "office365connectionname": {
          "type": "string",
          "value": "[parameters('name')]"
        },
        "office365endpointurl": {
          "type": "string",
          "value": "[reference(resourceId('Microsoft.Web/connections', parameters('name')),'2018-07-01-preview', 'full').properties.connectionRuntimeUrl]"
        }
      }
    steps:
    - task: AzureResourceManagerTemplateDeployment@3
      displayName: 'Validate ARM template'
      inputs:
        azureResourceManagerConnection: 'company-ais-dev'
        subscriptionId: '1xf291x0-0x61-4xx1-9097-777x44x1xxxx'
        resourceGroupName: 'rsg-company-dev'
        location: 'UK South'
        csmFile: src/Company.Azure.AIS.Common/Company.Azure.AIS.Common.Office365/azuredeploy.json
        csmParametersFile: src/Company.Azure.AIS.Common/Company.Azure.AIS.Common.Office365/azuredeploy.parameters.json
        deploymentMode: Validation
    steps:
    - task: PublishBuildArtifacts@1
      displayName: 'Publish Artifact: Company.Azure.AIS.Common.Office365'
      inputs:
        PathtoPublish: src/Company.Azure.AIS.Common/Company.Azure.AIS.Common.Office365
        ArtifactName: Company.Azure.AIS.Common.Office365
  3. And the same for the Logic App container with the following app settings
  4. 
    {
    ...
                {
                  "name": "WORKFLOWS_SUBSCRIPTION_ID",
                  "value": "[parameters('subscriptionId')]"
                },
                {
                  "name": "WORKFLOWS_LOCATION_NAME",
                  "value": "[parameters('locationName')]"
                },
                {
                  "name": "WORKFLOWS_RG_NAME",
                  "value": "[parameters('resourceGroupName')]"
                },
                {
                  "name": "OFFICE365_CONNECTION_ID", 
                  "value": "[parameters('office365connectionid')]"
                },
                {
                  "name": "OFFICE365_CONNECTION_RUNTIMEURL", 
                  "value": "[parameters('office365endpointurl')]"
                },
                {
                  "name": "OFFICE365_CONNECTION_NAME", 
                  "value": "[parameters('office365connectionname')]"
                }
    ...
    }
  5. In the Release Pipeline I used the Office365 artifact and the Logic App container artifact
  6. Release pipeline office365connection

  7. In the Release Pipeline Stage deployment, I do the following steps:
    Release logicapp pipeline with office365 connection (Bash)

        Ÿ Retrieve some Key Vault secrets that are required
        Ÿ Deploy the Office365 connection and output the API details
      steps:
      - task: AzureResourceManagerTemplateDeployment@3
        displayName: 'Deploy Office365 Connection'
        inputs:
          azureResourceManagerConnection: 'company-ais-dev'
          subscriptionId: '1xx291x0-0x61-4xx1-9097-777x44x1xxxx'
          resourceGroupName: 'rsg-company-dev'
          location: 'UK South'
          csmFile: '$(System.DefaultWorkingDirectory)/Company.Azure.AIS.Common.Office365/Company.Azure.AIS.Common.Office365/azuredeploy.json'
          csmParametersFile: '$(System.DefaultWorkingDirectory)/Company.Azure.AIS.Common.Office365/Company.Azure.AIS.Common.Office365/azuredeploy.parameters.json'
          overrideParameters: '-environment dev'
          deploymentOutputs: connectionOutputs
        Ÿ Run a Bash script to save the output variables into pipeline variables to be used in the Logic App container deployment
      steps:
      - bash: |
         # Echo the API connection outputs JSON and format it using sed
         echo "$(connectionOutputs)"
         formatted_json=$(echo \"$(connectionOutputs)\" | sed -e 's/ //g'  -e 's/}/"\n}/g'  -e 's/{/{\n"/g'  -e 's/:/":"/g'  -e 's/,/",\n"/g'  -e 's/"}/}/g'  -e 's/}"/}/g'  -e 's/"{/{/g'  -e 's/\[/\[\n"/g'  -e 's/]/"\n]/g'  -e 's/"\[/\[/g'  -e 's/]"/]/g' -e 's/https\":\"/https:/g')                   
         echo $?
         echo "$formatted_json"
         
         # Extract values using awk
         values=$(echo $formatted_json | awk -F'\"value\":\"' '{for (i=1; i<=NF; i++) {print $i}}' | awk -F'\"' '{print $1}')
         echo $?
         
         # Convert the space-separated values into a bash array
         value_array=($values) #IFS by default is space
         
         # Print extracted values
         echo "${value_array[0]}"
         echo "${value_array[1]}"
         echo "${value_array[2]}"
         
         # Set Azure DevOps pipeline variables
         echo "##vso[task.setvariable variable=office365connectionid]${value_array[0]}"
         echo "##vso[task.setvariable variable=office365connectionname]${value_array[1]}"
         echo "##vso[task.setvariable variable=office365endpointurl]${value_array[2]}"
        displayName: 'Save API connection outputs to pipeline variables'
        Ÿ Finally, use the Office365 API connection outputs to create the connection in the Logic App container
      variables:
        office365connectionid: ''
        office365endpointurl: ''
        office365connectionname: ''
      
      steps:
      - task: AzureResourceManagerTemplateDeployment@3
        displayName: 'Deploy VLE Logic App'
        inputs:
          azureResourceManagerConnection: 'company-ais-dev'
          subscriptionId: '1xx291x0-0x61-4xx1-9097-777x44x1xxxx'
          resourceGroupName: 'rsg-company-dev'
          location: 'UK South'
          csmFile: '$(System.DefaultWorkingDirectory)/Company.Azure.AIS.VLE.LogicApp/Company.Azure.AIS.VLE.LogicApp/azuredeploy.json'
          csmParametersFile: '$(System.DefaultWorkingDirectory)/Company.Azure.AIS.VLE.LogicApp/Company.Azure.AIS.VLE.LogicApp/azuredeploy.parameters.json'
          overrideParameters: '-environment dev -office365connectionid "$(office365connectionid)" -office365endpointurl "$(office365endpointurl)"                  -office365connectionname "$(office365connectionname)"'

The connection in the Logic App will look like this:

{
    "managedApiConnections": {
        "office365": {
            "api": {
                "id": "/subscriptions/@appsetting('WORKFLOWS_SUBSCRIPTION_ID')/providers/Microsoft.Web/locations/@appsetting('WORKFLOWS_LOCATION_NAME')/managedApis/office365"
            },
            "authentication": {
                "type": "ManagedServiceIdentity"
            },
            "connection": {
                "id": "/subscriptions/@appsetting('WORKFLOWS_SUBSCRIPTION_ID')/resourceGroups/@appsetting('WORKFLOWS_RG_NAME')/providers/Microsoft.Web/connections/@appsetting('OFFICE365_CONNECTION_NAME')"
            },
            "connectionRuntimeUrl": "@appsetting('OFFICE365_CONNECTION_RUNTIMEURL')"
        }
    }
}

So the connection is built up from the app settings, that were populated from the deployment of the actual Office365 Connection.

Therefore, the workflow actions will only need to reference the connection:

...
   "connection": {
   "referenceName": "office365"
   }
...

Leave a Reply

Your email address will not be published. Required fields are marked *