事件网格的 ARM 模板 API 与托管标识的连接

ARM template for Event Grid API Connection with managed identity

从逻辑应用创建新的事件网格连接时,可以select通过以下 3 种连接身份验证方法:

  1. 登录
  2. 服务主体
  3. 托管身份

#1 登录 要求用户以交互方式登录/验证。

#2 服务主体需要租户客户端IDClient Secret 要提供的值。

显然需要如何修改用于这种 API 连接的 ARM 模板: 需要添加如下。

"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 托管身份 只需要select 编辑托管身份。虽然很清楚如何以交互方式创建这样的 API 连接,但我找不到有关此类身份验证方法的 ARM 模板格式的任何信息。

所以问题是 - 用于事件网格连接的 ARM 模板究竟应该如何与(更新用户分配)托管标识看起来像?这样创建的 API 连接如下所示:

更新:我需要在我的逻辑应用程序中使用用户分配的托管身份。下面提供了一个适用于 系统分配的 管理身份的答案,但不适用于 用户分配的 管理身份。如果有人可以为使用 用户分配的 托管身份的 API 连接建议 ARM 模板,我们将不胜感激。

如果要创建事件网格API与托管身份的连接,请参考以下步骤

  1. 在 Azure 逻辑应用中启用系统分配的标识
{
   "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. 授予身份访问资源
{
    "$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. 创建连接
{
            "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. 创建触发器
{
    "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"
                }
            }
        }
    }

更多详情请参考

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

答案似乎是,目前,看到这仍在预览中 (afaik)

要使用 ARM 模板创建托管身份 api 连接,您需要包含“parameterValueType”:“Alternative”

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

我没有找到关于此 属性 的文档。我发现的唯一原因是查看我使用门户创建的 api 连接的原始 json(json 视图)。

我有一个 ARM 模板,它将部署事件网格自定义主题和逻辑应用程序并使用托管标识连接订阅。

ARM 模板是:

{
"$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'))]"
        ]
    }
]
}

示例参数文件是:

{
"$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"
    }
}
}

当我将此模板加载到 Visual Studio 2019 Logic App 设计器中时,我遇到了一个问题,我已在此处记录:

Visual Studio 2019 Logic Apps Designer removing code

由于您可以拥有多个用户托管身份,因此仅 select ManagedServiceIdentity 是不够的。相反,您必须包含您希望使用的身份的 ID。

扩展@jim-xu 的回答:

连接示例:

    {
        "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"
        }
    }

这里的parameterValueType是一个很重要的设置。如 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...

连接随后被逻辑应用引用,并将标识作为 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')]"
                        }
                    }
                }

请注意在事件网格连接的 authentication 部分添加了 identity 字段。

Microsoft 文档中提供了有关此的更多信息:https://docs.microsoft.com/en-us/azure/logic-apps/create-managed-service-identity?tabs=consumption#create-user-assigned-identity-in-an-arm-template-consumption-only

标识值应为托管标识的 ID。您可以通过 Azure 门户查看托管身份的 JSON 视图来获取它。