道歉很长,但是我在这个问题上已经工作了好几天了,我似乎找不到解决方法。
我想通过将Azure Cosmos DB放置在虚拟网络(VNet)中来限制对它的访问,并且只允许通过Function应用程序进行访问。
第一部分很简单:创建一个Cosmos DB和一个VNet并按照here所述配置数据库的服务端点。
将Function应用程序连接到VNet可以通过两种方式完成。
按照this指南,我已经用网关子网配置了VNet,并按照说明添加和配置了VPN网关。
之后,我将网关子网添加到Cosmos DB服务端点配置并设置了我的Function App
此方法更易于设置,但如microsoft docs中所述,不适用于生产工作负载。
配置更加容易,但是由于结果相同,因此在本文的其余部分中我省略了此选项。
尝试从我的功能应用程序连接到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。
我的直觉是这是某个地方的配置问题,但我无法找到位置。我会继续搜索,但我们将不胜感激。
答案 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虚拟网络中。当然,这是一个很高的规模和成本。