10p
10p

Reputation: 6793

ARM template for Event Grid API Connection with managed identity

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.

Upvotes: 3

Views: 4674

Answers (4)

Brian Sidebotham
Brian Sidebotham

Reputation: 1906

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.

Upvotes: 2

Bjørn Jansen
Bjørn Jansen

Reputation: 11

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.

Upvotes: 1

Jim Xu
Jim Xu

Reputation: 23141

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

Upvotes: 0

finarne
finarne

Reputation: 61

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

Upvotes: 1

Related Questions