2

When creating a new Event Grid connection from a Logic App, one can select from the following 3 authentication methods for the connection:

  1. Sign in
  2. Service principal
  3. Managed identity

#1 Sign in requires a user to sign in / authenticate interactively.

#2 Service principal requires Tenant, Client ID, and Client Secret values to be provided.

It is clear how an ARM template for such an API connection would need to be amended: the parameterValues need to be added as follows.

"parameterValues": {
  "token:clientId": "[parameters('ConnectionClientId')]",
  "token:clientSecret": "[parameters('ConnectionClientSecret')]",
  "token:TenantId": "[parameters('ConnectionTenantId')]",
  "token:resourceUri": "https://management.core.windows.net/",
  "token:grantType": "client_credentials"
}

#3 Managed identity requires only the managed identity to be selected. While it is clear how to create such an API connection interactively, I couldn't find any information on the ARM template format for such an authentication method.

So the question is - how exactly should an ARM template for Event Grid connection with a (update: user assigned) managed identity look like? So that the created API connection looks as follows:

API Connection with managed identity

Update: I need to use a user assigned managed identity in my Logic App. An answer has been provided below that works for system assigned managed identities, but not for user assigned ones. If someone can advise an ARM template for an API connection that uses a user assigned managed identity, that will be appreciated.

10p
  • 5,488
  • 22
  • 30

4 Answers4

1

The answer seems to be, at the moment, seeing as this is still in preview (afaik)

To create a managed Identity api connection using ARM Templates, you need to include "parameterValueType": "Alternative"

"properties": {
  "displayName": "ARM API connection",
  "customParameterValues": {},
  "parameterValueType": "Alternative",
  "api": {
    "id": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', resourceGroup().location, '/managedApis/arm')]"
  }
}

I've found no documentation of this property. The only reason I found out was by looking at the raw json (json view) of an api connection I created using the portal.

Gustavo Mori
  • 8,319
  • 3
  • 38
  • 52
  • Thanks @Bjorn, I've tried your suggestion. Instead of '/managedApis/arm' I believe '/managedApis/azureeventgrid' should be used.The only other bit that I see different from the standard template is "parameterValueType": "Alternative". For some reason, the deployment starts and never completes. I waited for a while and then had to cancel it. Another thing, I'd expect the managed identity ID to be provided somewhere. I don't see how the deployment can succeed if it's not clear what managed identity needs to be used. Any idea how to specify it in the template? – 10p Feb 03 '21 at 09:58
  • Yes, it should be azureeventgrid. I have no experience with those myself yet, but i assume it works the same way for those connectors. – Bjørn Jansen Feb 03 '21 at 23:27
  • As for the managed identity, it is provided by inserting "identity": { "type": "SystemAssigned" }, Into the arm template of the logic app as Jim Xu said. Azure will insert the appropriate ids into the deployed template, as it is a managed identity. You could have a look at deployments in the resourcegroup in the portal. That might give you some clues as to why its failing. You can also try manually deleting all the resources you are trying to deploy, to see if that helps. – Bjørn Jansen Feb 03 '21 at 23:35
  • The API Connection has to be deployed before the Logic App. When an API Connection is created via front-end (from Logic App) and you go to its properties, it shows "This connection can only be used with a managed identity" and you cannot make any changes (see screenshot). The managed identity details are already pre-configured there. If an API Connection is created from ARM template and you go to its properties, it has an "Authorize" button, which can be used to update the connection. Having "identity" details in the Logic App does not affect API Connection config, which is deployed first. – 10p Feb 04 '21 at 11:42
  • Same Event Grid API Connection can be used by different Logic Apps - and it works very well for me when I create the API Connection manually. I have "`"identity":{"type":"UserAssigned","userAssignedIdentities":{"...":{}}}`" in the Logic App templates. Despite having the user assigned identity set up in the Logic Apps, the API Connection template also has to have the managed identity specified somehow. – 10p Feb 04 '21 at 11:45
  • 10p This identity json you put in logic app or in connection? – zolty13 Feb 21 '21 at 22:05
  • Does anyone tries it with connect to Key Vault? There is an error during runtime: *The connection does not contain a vault name. Please edit the connection and enter a valid key vault name.* – zolty13 Feb 21 '21 at 22:12
  • @zolty13, that "identity" JSON from my comment above is from the Logic App. – 10p Sep 24 '21 at 15:44
  • @BjørnJansen, a similar template was provided in finarne's answer. I was finally able to test it. It does work but only with system assigned identities. I needed to use a user assigned identity in my Logic Apps. I should have made it clear in my question. When I am trying to use an API connection created from the suggested ARM template, the error is InvalidWorkflowManagedIdentitySpecified: "The workflow '...' does not contain the managed identity of type 'SystemAssigned'." – 10p Sep 24 '21 at 15:59
1

I have an ARM template that will deploy an Event Grid Custom Topic and Logic App and wire up a subscription using a Managed Identity.

The ARM template is:

{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
    "workflows_lgeventgridtriggermaindev_name": {
        "type": "String"
    },
    "topics_eglogicappscratchtestdev_externalid": {
        "type": "String"
    },
    "topics_eglogicappscratchtestdev_name": {
        "type": "String"
    },
    "topics_eglogicappscratchtestdev_lgsubscriptionName": {
        "type": "String"
    },
    "LogicAppLocation": {
        "type": "string",
        "minLength": 1,
        "defaultValue": "northeurope"
    },
    "azureeventgrid_1_Connection_Name": {
        "type": "string",
        "defaultValue": "azureeventgrid"
    },
    "azureeventgrid_1_Connection_DisplayName": {
        "type": "string",
        "defaultValue": "lgapiegscratch"
    }
},
"variables": {
    "targetLogicApp": {
        "triggerId": "[resourceId('Microsoft.Logic/workflows/triggers', parameters('workflows_lgeventgridtriggermaindev_name'), 'When_a_resource_event_occurs')]"
    }
},
"resources": [
    {
        "type": "Microsoft.EventGrid/topics",
        "apiVersion": "2021-06-01-preview",
        "name": "[parameters('topics_eglogicappscratchtestdev_name')]",
        "location": "uksouth",
        "sku": {
            "name": "Basic"
        },
        "kind": "Azure",
        "identity": {
            "type": "None"
        },
        "properties": {
            "inputSchema": "EventGridSchema",
            "publicNetworkAccess": "Enabled"
        }
    },
    {
        "type": "MICROSOFT.WEB/CONNECTIONS",
        "apiVersion": "2018-07-01-preview",
        "name": "[parameters('azureeventgrid_1_Connection_Name')]",
        "location": "[parameters('LogicAppLocation')]",
        "properties": {
            "api": {
                "id": "[concat(subscription().id, '/providers/Microsoft.Web/locations/', parameters('LogicAppLocation'), '/managedApis/', 'azureeventgrid')]"
            },
            "displayName": "[parameters('azureeventgrid_1_Connection_DisplayName')]",
            "parameterValueType": "Alternative"
        }
    },
    {
        "type": "Microsoft.Logic/workflows",
        "apiVersion": "2017-07-01",
        "name": "[parameters('workflows_lgeventgridtriggermaindev_name')]",
        "location": "[parameters('LogicAppLocation')]",
        "identity": {
            "type": "SystemAssigned"
        },
        "properties": {
            "state": "Enabled",
            "definition": {
                "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
                "actions": {
                    "getTopicData": {
                        "type": "Compose",
                        "inputs": "@triggerBody()?['data']",
                        "runAfter": {}
                    }
                },
                "parameters": {
                    "$connections": {
                        "defaultValue": {},
                        "type": "Object"
                    }
                },
                "triggers": {
                    "When_a_resource_event_occurs": {
                        "type": "ApiConnectionWebhook",
                        "inputs": {
                            "host": {
                                "connection": {
                                    "name": "@parameters('$connections')['azureeventgrid']['connectionId']"
                                }
                            },
                            "body": {
                                "properties": {
                                    "topic": "[parameters('topics_eglogicappscratchtestdev_externalid')]",
                                    "destination": {
                                        "endpointType": "webhook",
                                        "properties": {
                                            "endpointUrl": "@{listCallbackUrl()}"
                                        }
                                    },
                                    "filter": {
                                        "includedEventTypes": [
                                            "TriggerLogicApp"
                                        ],
                                        "subjectBeginsWith": "Main"
                                    }
                                }
                            },
                            "path": "[concat('/subscriptions/@{encodeURIComponent(''', subscription().subscriptionId, ''')}/providers/@{encodeURIComponent(''Microsoft.EventGrid.Topics'')}/resource/eventSubscriptions')]",
                            "queries": {
                                "x-ms-api-version": "2017-06-15-preview"
                            }
                        },
                        "splitOn": "@triggerBody()"
                    }
                },
                "contentVersion": "1.0.0.0",
                "outputs": {}
            },
            "parameters": {
                "$connections": {
                    "value": {
                        "azureeventgrid": {
                            "id": "[concat(subscription().id, '/providers/Microsoft.Web/locations/', parameters('LogicAppLocation'), '/managedApis/', 'azureeventgrid')]",
                            "connectionId": "[resourceId('Microsoft.Web/connections', parameters('azureeventgrid_1_Connection_Name'))]",
                            "connectionName": "[parameters('azureeventgrid_1_Connection_Name')]",
                            "connectionProperties": {
                                "authentication": {
                                    "type": "ManagedServiceIdentity"
                                }
                            }
                        }
                    }
                }
            }
        },
        "tags": {
            "displayName": "LogicApp"
        },
        "dependsOn": [
            "[resourceId('Microsoft.Web/connections', parameters('azureeventgrid_1_Connection_Name'))]",
            "[resourceId('Microsoft.EventGrid/topics', parameters('topics_eglogicappscratchtestdev_name'))]"
        ]
    },
    {
        "name": "[parameters('topics_eglogicappscratchtestdev_lgsubscriptionName')]",
        "scope": "[format('Microsoft.EventGrid/topics/{0}', parameters('topics_eglogicappscratchtestdev_name'))]",
        "type": "Microsoft.EventGrid/eventSubscriptions",
        "location": "[parameters('LogicAppLocation')]",
        "apiVersion": "2020-04-01-preview",
        "properties": {
            "destination": {
                "endpointType": "WebHook",
                "properties": {
                    "endpointUrl": "[listCallbackUrl(variables('TargetLogicApp').triggerId, '2019-05-01').value]"
                }
            },
            "filter": {
                "subjectBeginsWith": "Main",
                "includedEventTypes": [
                    "TriggerLogicApp"
                ]
            }
        },
        "dependsOn": [
            "[resourceId('Microsoft.Web/connections', parameters('azureeventgrid_1_Connection_Name'))]"
        ]
    }
]
}

An example parameters file is:

{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
  "workflows_lgeventgridtriggermaindev_name": {
        "value": "lgeventgridtriggerscratch"
    },
    "topics_eglogicappscratchtestdev_externalid": {
        "value": "/subscriptions/<subscriptionid>/resourceGroups/<resourcegroupname>/providers/Microsoft.EventGrid/topics/eglogicappscratch"
    },
    "topics_eglogicappscratchtestdev_name": {
        "value": "eglogicappscratch"
    },
    "topics_eglogicappscratchtestdev_lgsubscriptionName": {
        "value": "lgeventgridtriggerscratchsub"
    },
    "LogicAppLocation": {
        "value": "uksouth"
    },
    "azureeventgrid_1_Connection_Name": {
        "value": "azureeventgrid"
    },
    "azureeventgrid_1_Connection_DisplayName": {
        "value": "lgapiegscratch"
    }
}
}

When I load this template into the Visual Studio 2019 Logic App designer I get an issue I've documented here:

Visual Studio 2019 Logic Apps Designer removing code

finarne
  • 51
  • 6
  • Thanks, I tested it and it does work for system assigned identities. Unfortunately, it doesn't work when the Logic App uses a user assigned identity. The error is InvalidWorkflowManagedIdentitySpecified: "The workflow '...' does not contain the managed identity of type 'SystemAssigned'." :( – 10p Sep 24 '21 at 15:37
1

As you can have multiple User Managed Identities, it's not enough to simply select the ManagedServiceIdentity. Instead, you must include the ID of the Identity that you wish to use.

Expanding on @jim-xu's answer:

An example connection:

{
  "type": "Microsoft.Web/connections",
  "apiVersion": "2016-06-01",
  "name": "[variables('eventApiConnectionName')]",
  "location": "[resourceGroup().location]",
  "kind": "V1",
  "tags": "[parameters('resourceTags')]",
  "properties": {
    "displayName": "[variables('eventApiConnectionName')]",
    "customParameterValues": {},
    "api": {
      "id": "[subscriptionResourceId('Microsoft.Web/locations/managedApis', resourceGroup().location, 'azureeventgrid')]"
    },
    "parameterValueType": "Alternative"
  }
}

The parameterValueType here is an important setting. As noted in the MicroSoft documnetation:

If you automate deployment with an ARM template, and your logic app workflow includes a managed connector trigger or action that uses a managed identity, confirm that the underlying connection resource definition includes the parameterValueType property with Alternative as the property value. Otherwise, your ARM deployment won't set up the connection to use the managed identity for authentication...

The connection is then referenced by the logic app, and includes the identity as a resourceId:

"$connections": {
  "value": {
    "azureeventgrid": {
      "connectionId": "[concat('/subscriptions/', subscription().subscriptionId, '/resourceGroups/', resourceGroup().name, '/providers/Microsoft.Web/connections/', variables('eventApiConnectionName'))]",
      "connectionName": "[variables('eventApiConnectionName')]",
      "connectionProperties": {
        "authentication": {
          "type": "ManagedServiceIdentity",
          "identity": "[parameters('userManagedIdentity')]"
        }
      },
      "id": "[concat('/subscriptions/',subscription().subscriptionId, '/providers/Microsoft.Web/locations/', resourceGroup().location, '/managedApis/azureeventgrid')]"
    }
  }
}

Notice the addition of the identity field in the authentication section of the eventgrid connection.

Further information regarding this is available in the MicroSoft documentation: https://learn.microsoft.com/en-us/azure/logic-apps/create-managed-service-identity?tabs=consumption#create-user-assigned-identity-in-an-arm-template-consumption-only

The identity value should be the ID of the managed identity. You can get that through the Azure portal by looking at the JSON view of the managed identity.

Gustavo Mori
  • 8,319
  • 3
  • 38
  • 52
Brian Sidebotham
  • 1,706
  • 11
  • 15
  • Thank you for your input, but it doesn't answer the question. The question is not about creating a Logic App with a managed identity. It's about creating an **Event Grid API connection**, which would use a *user assigned managed identity*. – 10p Dec 07 '21 at 23:26
  • @10p That's what I'm saying, you need to add the identity field in to the authentication object above (which is an event grid API connection) and then it uses a user assigned managed identity. I've been through this pain and this is working for me. :) – Brian Sidebotham Dec 08 '21 at 12:02
  • Brian, if this works for you, could you please also add to the answer the API connection ARM template you're using. I'll try to deploy both the API connection and the Logic App using the code that works for you and check whether it works for me as well. The reason I'm asking is that for *existing API connection* I have no problem deploying a Logic App, which would use it successfully. I need to be able to deploy both. Thanks. – 10p Dec 09 '21 at 14:04
  • @10p Sure, I'll add in the connection resource too. – Brian Sidebotham Dec 09 '21 at 14:10
  • 1
    @10p Just added a little more info pertinent to the connection and it's `parameterValueType` property. – Brian Sidebotham Dec 09 '21 at 14:28
  • 2
    Bingo! 10 months after the question was asked the mystery is resolved Using `"parameterValueType": "Alternative"` in the API connection template and `"authentication": { "type": "ManagedServiceIdentity", "identity": "[parameters('userManagedIdentity')]" }` in the Logic App template did the trick. Thanks! – 10p Dec 13 '21 at 15:38
0

If you want to create Event Grid API Connection with managed identity, please refer to the following steps

  1. Enable system-assigned identity in Azure Logic app
{
  "apiVersion": "2016-06-01",
  "type": "Microsoft.logic/workflows",
  "name": "[variables('logicappName')]",
  "location": "[resourceGroup().location]",
  "identity": {
    "type": "SystemAssigned"
  },
  "properties": {
    "definition": {
      "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
      "actions": {},
      "parameters": {},
      "triggers": {},
      "contentVersion": "1.0.0.0",
      "outputs": {}
    },
    "parameters": {},
    "dependsOn": []
  }
  1. Give identity access to resources
{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "resources": [
    {
      "type": "Microsoft.Authorization/roleAssignments",
      "apiVersion": "2018-09-01-preview",
      "name": "[guid(resourceGroup().id)]",
      "properties": {
        "roleDefinitionId": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Authorization/roleDefinitions/', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]",
        "principalId": "[reference(resourceId('Microsoft.Logic/workflows','<logic app name>'),'2016-06-01','Full').identity.principalId]"
      }
    }
  ]
}
  1. Create connection
{
  "type": "Microsoft.Web/connections",
  "apiVersion": "2016-06-01",
  "name": "",
  "location": "",
  "kind": "V1",
  "properties": {
    "displayName": "test",
    "customParameterValues": {},
    "api": {
      "id": "/subscriptions/<>/providers/Microsoft.Web/locations/<>/managedApis/azureeventgrid"
    }
  }
}
  1. Create trigger
{
  "definition": {
    "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json",
    "actions": {},
    "contentVersion": "1.0.0.0",
    "outputs": {},
    "parameters": {
      "$connections": {
        "defaultValue": {},
        "type": "Object"
      }
    },
    "triggers": {
      "When_a_resource_event_occurs": {
        "inputs": {
          "body": {
            "properties": {
              "destination": {
                "endpointType": "webhook",
                "properties": {
                  "endpointUrl": "@{listCallbackUrl()}"
                }
              },
              "topic": ""
            }
          },
          "host": {
            "connection": {
              "name": "@parameters('$connections')['azureeventgrid']['connectionId']"
            }
          },
          "path": "/subscriptions/{Azure-subscription-ID}/providers/{}/resource/eventSubscriptions",
          "queries": {
            "x-ms-api-version": "2017-09-15-preview"
          }
        },
        "splitOn": "@triggerBody()",
        "type": "ApiConnectionWebhook"
      }
    }
  },
  "parameters": {
    "$connections": {
      "value": {
        "azureeventgrid": {
          "connectionId": "/subscriptions/{Azure-subscription-ID}/resourceGroups/{resourcegroup}/providers/Microsoft.Web/connections/{connection-name}",
          "connectionName": "{connection-name}",
          "connectionProperties": {
            "authentication": {
              "type": "ManagedServiceIdentity"
            }
          },
          "id": "/subscriptions/{Azure-subscription-ID}/providers/Microsoft.Web/locations/{Azure-region}/managedApis/azureeventgrid"
        }
      }
    }
  }

For more details, please refer to

https://learn.microsoft.com/en-us/azure/logic-apps/create-managed-service-identity

Gustavo Mori
  • 8,319
  • 3
  • 38
  • 52
Jim Xu
  • 21,610
  • 2
  • 19
  • 39
  • 1
    That doesn't create an API connection authenticated with a managed identity. Step 3 would create an API connection that would still have to be authenticated by a user manually. I already have a managed identity and I can successfully create an Event Grid API connection manually (from Logic App designer) using this managed identity (user-assigned, not system-assigned). See the screenshot of the created API connection in my question. I need to be able to create such an API connection via ARM template, not manually. – 10p Jan 28 '21 at 09:27
  • anyone know how to creater connection with Managed identity auth? – zolty13 Feb 21 '21 at 21:05