Service Principal for Logic App Connector


Azure Logic Apps is a powerful integration platform.

It integrates with different services (inside and outside Azure) using connectors.

Connectors are responsible to authenticate to the service they represent.

Some connectors will hold the credentials. This is the case, for instance, of the SQL connector.

Other connectors will by default take the AAD identity of a user. This is the case, for instance, of Data Factory. In the case of Data Factory, it uses the AAD to access the Azure REST API.

When we create those connectors in the Portal, they take our identity. This is done in one flow where we authorize it. This approach is problematic on multiple levels.

It requires the access token generated from the authorization to be refreshed. A tenant will have a time out when refresh is no longer authorized. The user then has to re-authorize in the Portal. This isn’t a great production operation. In general, the traceability will be done on the end user. This is sub-optimal too.

A more robust approach is to use an AAD Service Principal. In that case, the credentials of the principal are stored with the connector.

We will explore that approach in this article. We will use the Data Factory but this could be used with any connector requiring an AAD account.

As usual, the code is available in GitHub and we can deploy the solution here:

Deploy button

Deployment

The deployment requires the following 5 parameters:

Name Description
Data Factory Name Name of the Data Factory. This needs to be globally unique.
Service Principal App Id Application ID of the Service Principal.
Service Principal Object Id Object ID of the Service Principal.
Service Principal Secret Secret used to authenticate the Service Principal.
Service Principal Tenant Tenant (i.e. AAD tenant) where the Service Principal lives.

We covered the creation of a service principal in a past article.

The region we select needs to support Data Factory which isn’t supported everywhere. East US is a supported region.

This should deploy the following resources:

Deployment

Connection with current user

Let’s first look at df-connection-current-user. This connector is configured, as its name suggests, to use the current user.

Current user

We see a warning telling us the connection isn’t authenticated.

We’ve seen how to create Logic Apps Connector in a past article. The ARM Template used here was:

{
    "type": "microsoft.web/connections",
    "apiVersion": "2016-06-01",
    "name": "[variables('Current User Data Factory Connection Name')]",
    "location": "[resourceGroup().location]",
    "dependsOn": [],
    "properties": {
        "api": {
            "id": "[concat(subscription().id, '/providers/Microsoft.Web/locations/', resourceGroup().location, '/managedApis/azuredatafactory')]"
        },
        "displayName": "Current User Data Factory Connection"
    }
}

If we click on the warning, we are taken to the following form:

Authorization

If we click the authorize button, we are going to authenticate as ourselves.

Connection with Service Principal

Now, let’s got to df-connection-principal. This connector is configured to use the service principal credentials passed to the ARM template.

It doesn’t display any warning.

The ARM Template used here was:

{
    "type": "microsoft.web/connections",
    "apiVersion": "2016-06-01",
    "name": "[variables('Principal Data Factory Connection Name')]",
    "location": "[resourceGroup().location]",
    "dependsOn": [],
    "properties": {
        "api": {
            "id": "[concat(subscription().id, '/providers/Microsoft.Web/locations/', resourceGroup().location, '/managedApis/azuredatafactory')]"
        },
        "displayName": "Service Princiapl Data Factory Connection",
        "parameterValues": {
            "token:clientId": "[parameters('Service Principal App Id')]",
            "token:clientSecret": "[parameters('Service Principal Secret')]",
            "token:TenantId": "[parameters('Service Principal Tenant')]",
            "token:resourceUri": "https://management.core.windows.net/",
            "token:grantType": "client_credentials"
        }
    }
}

Credentials are passed in the configuration. There is no need to authorize / authenticate.

Logic App integration

Now let’s go to the logic app. Let’s open its designer experience.

The logic app is trivial. It is a 2 steps app: one http trigger and one action.

The action is the creation of a pipeline run. For some reason that doesn’t render the information. If we look at the code view, we can find the path under Create_a_pipeline_run. The path points to the master pipeline.

Let’s Run the Logic App.

It should complete successfully quickly.

Data Factory logs

Now if we finally go to the Data Factory.

If we look at the activity logs, we should see something like the following:

Logs

In our case we see the last operation, a Create Pipeline Run was done by Vpl-Principal, which is the name of our Service Principal.

So the traceability goes to the configured service principal.

Role Assignment

In order for this sample to work, we needed to give the Service Principal the Data Factory Contributor role on the Data Factory.

We’ve seen how to do role assignment in ARM Template in a past article.

{
    "type": "Microsoft.DataFactory/factories/providers/roleAssignments",
    "apiVersion": "2017-05-01",
    "name": "[variables('Data Factory Assignment Name')]",
    "dependsOn": [
        "[resourceId('Microsoft.DataFactory/factories', parameters('Data Factory Name'))]"
    ],
    "properties": {
        "roleDefinitionId": "[variables('Full Data Factory Contributor Role Definition ID')]",
        "principalId": "[parameters('Service Principal Object Id')]"
    }
}

We could have assigned the role at the resource group level but we prefer to limit the scope.

Summary

As we get closer to production-ready with Logic Apps, there are some designer convenience we want to drop.

One of those is to authenticate connectors as ourselves.

We’ve seen how to do this using a service principal.


3 thoughts on “Service Principal for Logic App Connector

  1. I spent a week looking for the connection “parameterValues” required for the service principal. Thank you for finding them and posting them!

Leave a comment