通过功能应用程序访问虚拟网络中的Cosmos DB

时间:2019-02-27 08:29:37

标签: azure-functions azure-cosmosdb azure-virtual-network

道歉很长,但是我在这个问题上已经工作了好几天了,我似乎找不到解决方法。

情况

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

方法

第一部分很简单:创建一个Cosmos DB和一个VNet并按照here所述配置数据库的服务端点。

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

使用网关

按照this指南,我已经用网关子网配置了VNet,并按照说明添加和配置了VPN网关。

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

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

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

配置

VNet

GatewaySubnet configuration

网关

Point-to-site configuration

Cosmos DB

Cosmos DB Configuration

功能应用程序

Function App VNet configuration

问题

尝试从我的功能应用程序连接到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"
}

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

作为测试,我遵循了this教程,并添加了VM并设置了代理。这样可以正常工作,因此Function应用程序可以访问VNet。

我的直觉是这是某个地方的配置问题,但我无法找到位置。我会继续搜索,但我们将不胜感激。

使用的在线资源

1 个答案:

答案 0 :(得分:2)

我相信您的配置是正确的,因为两种方法都无法按您期望的方式工作。

对于VNet Integration feature,您可以使用此网关安全地访问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功能也不是授权子网中的资源。

当您在Azure VNet中添加VM并按照integrating a Function App with an Azure Virtual Network的过程设置代理时。在这种情况下,VM是部署在Azure VNet中的资源。因此,您可以使用VNet集成功能在私有VNet中访问它。

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