从 Function 应用访问虚拟网络中的 Cosmos DB

G.S*_*ers 5 azure-virtual-network azure-functions azure-cosmosdb

对这么长的帖子表示歉意,但我已经在这个问题上工作了几天,但似乎找不到解决方案。

情况

我想通过将 Azure 中的 Cosmos DB 放置在虚拟网络 (VNet) 中来限制对它的访问,并且只允许通过 Function 应用进行访问。

方法

第一部分很简单:创建 Cosmos DB 和 VNet,并按照此处所述配置数据库的服务终结点。

将 Function 应用连接到 VNet 可以通过两种方式完成。

使用网关

按照指南,我已使用网关子网配置我的 VNet,并按所述添加和配置 VPN 网关。

之后,我将网关子网添加到 Cosmos DB 服务端点配置并设置我的 Function App

使用 VNet(预览)功能选择子网

这种方法更容易设置,但正如微软文档中所述,它不适用于生产工作负载。
配置更容易,但由于结果是相同的,我在本文的其余部分中省略了此选项。

配置

互联网络

网关子网配置

网关

点到站点配置

宇宙数据库

Cosmos 数据库配置

功能应用程序

功能应用程序VNet配置

问题

尝试从函数应用连接到 Cosmos DB 时,我不断收到连接错误:

{
    "Message": "An error has occurred.",
    "ExceptionMessage": "Unable to proceed with the request. Please check the authorization claims to ensure the required permissions to process the request.\r\nActivityId: f784890f-2e1a-4e36-bfb9-8f62ff32c034, Microsoft.Azure.Documents.Common/2.2.0.0, Windows/10.0.14393 documentdb-netcore-sdk/2.2.2",
    "ExceptionType": "Microsoft.Azure.Documents.DocumentClientException",
    "StackTrace": "   at Microsoft.Azure.Documents.Client.ClientExtensions.ParseResponseAsync(HttpResponseMessage responseMessage, JsonSerializerSettings serializerSettings, Boolean throwOnKnownClientErrorCodes)\r\n   at Microsoft.Azure.Documents.Client.GatewayServiceConfigurationReader.GetDatabaseAccountAsync(Uri serviceEndpoint)\r\n   at Microsoft.Azure.Documents.Routing.GlobalEndpointManager.GetDatabaseAccountFromAnyLocationsAsync(Uri defaultEndpoint, IList`1 locations, Func`2 getDatabaseAccountFn)\r\n   at Microsoft.Azure.Documents.Client.GatewayServiceConfigurationReader.InitializeReaderAsync()\r\n   at Microsoft.Azure.Documents.Client.DocumentClient.InitializeGatewayConfigurationReader()\r\n   at Microsoft.Azure.Documents.Client.DocumentClient.GetInitializationTask()\r\n   at Microsoft.Azure.Documents.Client.DocumentClient.EnsureValidClientAsync()\r\n   at Microsoft.Azure.Documents.Client.DocumentClient.ReadDatabasePrivateAsync(String databaseLink, RequestOptions options, IDocumentClientRetryPolicy retryPolicyInstance)\r\n   at Microsoft.Azure.Documents.BackoffRetryUtility`1.<>c__DisplayClass1_0.<<ExecuteAsync>b__0>d.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at Microsoft.Azure.Documents.BackoffRetryUtility`1.ExecuteRetryAsync(Func`1 callbackMethod, Func`3 callShouldRetry, Func`1 inBackoffAlternateCallbackMethod, TimeSpan minBackoffForInBackoffCallback, CancellationToken cancellationToken, Action`1 preRetryCallback)\r\n   at Microsoft.Azure.Documents.ShouldRetryResult.ThrowIfDoneTrying(ExceptionDispatchInfo capturedException)\r\n   at Microsoft.Azure.Documents.BackoffRetryUtility`1.ExecuteRetryAsync(Func`1 callbackMethod, Func`3 callShouldRetry, Func`1 inBackoffAlternateCallbackMethod, TimeSpan minBackoffForInBackoffCallback, CancellationToken cancellationToken, Action`1 preRetryCallback)\r\n   at Microsoft.Azure.Documents.BackoffRetryUtility`1.ExecuteAsync(Func`1 callbackMethod, IRetryPolicy retryPolicy, CancellationToken cancellationToken, Action`1 preRetryCallback)\r\n   at Microsoft.Azure.Documents.Client.DocumentClient.CreateDatabaseIfNotExistsPrivateAsync(Database database, RequestOptions options)\r\n   at VnetTestFunction.Function1.Run(HttpRequest req, ILogger log) in C:\\Development\\VnetTestFunction\\VnetTestFunction\\Function1.cs:line 39"
}
Run Code Online (Sandbox Code Playgroud)

这些方法之间没有区别。在这两种情况下,我的函数应用程序和数据库之间都没有连接。

作为测试,我按照教程添加了虚拟机并设置了代理。这有效,因此 Function 应用可以访问 VNet。

我的直觉告诉我这是某个地方的配置问题,但我无法找出哪里。我会继续搜索,但非常感谢任何帮助。

使用的在线资源

Nan*_*ong 4

我相信您的配置是正确的,因为这两种方法都不应该按您的意愿工作。

对于VNet 集成功能,您可以使用此网关安全地访问 VNet 中的资源。

VNet 集成使您的 Web 应用(或函数应用)可以访问虚拟网络中的资源,但不会授予从虚拟网络对 Web 应用的私有访问权限。

另外,Cosmos DB 不是 Azure VNet 内部的资源,实际上您并没有使用此方法限制 Azure 功能对 Cosmos DB 的访问。您的 Function App 同时连接到 Internet 和 VNET。通过 Internet 从 Function App 到 Cosmos DB 仍然有效。

此外,一旦在特定子网中启用 Cosmos DB 服务终结点,这实际上会限制通过虚拟网络中此授权子网的连接对 Azure Cosmos DB 帐户的访问。如果在Cosmos DB的防火墙中只配置授权子网,我认为只有来自授权子网的请求才能绕过防火墙。在这种情况下,Azure function 也不是授权子网中的资源。

当您在 Azure VNet 中添加 VM 并按照将Function App 与 Azure 虚拟网络集成的过程设置代理时。在此场景中,VM 是部署在 Azure VNet 中的资源。因此,您可以使用 VNet 集成功能在私有 VNet 中访问它。

据我所知,如果您希望在 VNet 内使用 Azure Function App,则可以在App Service Environments中部署应用程序服务,该环境将 Azure App Service 直接部署到 Azure 虚拟网络中。当然,这是一个非常高的规模和成本。