首页 > 解决方案 > 从 Lambda 连接到 Neptune 的问题

问题描述

我创建了一个简单的 AWS Neptune 集群,有一个写入器,没有只读副本。我使用该选项为它创建了一个新的 VPC,并且也自动为它创建了两个安全组。

我还有一个调用 Nepture 集群端点的 Lambda。我已经使用 Neptune 集群的 VPC 配置了 Lambda,指定了它的所有子网和上面提到的两个安全组。在我从 AWS 控制台执行 VPC 配置时自动分配入站和出站规则后,我没有手动修改它们(只需完成这些步骤)。

Lambda 是用 Python 编写的,并使用该requests库通过 AWS Singature V4 进行 HTTPS 调用。Lambda 的执行角色有NeptuneFullAccess一个内联策略,允许为 Lambda 配置 VPC(已完成,因此该策略有效)。

Lambda 在端口 8182 上调用 Neptune 集群的终端节点,其中集群的名称和 ID 已编辑:

https://NAME.cluster-ID.us-east-1.neptune.amazonaws.com:8182

我收到以下错误:

{
  "errorMessage": "2020-05-20T21:26:35.066Z c8ee70ac-6390-48fd-a32e-36f80d58a24e Task timed out after 3.00 seconds"
}

我究竟做错了什么?

更新:因此,看起来 Neptune 集群的第二个安全组是由我在创建集群时选择一个选项创建的。因此,我再次尝试使用Choose existing安全组选项,而不是Create new. (我想我之前很困惑,因为我正在创建一个全新的 VPC,那么安全组怎么可能已经存在?但是向导只是假设default那时将创建的安全组。)

现在,我不再遇到同样的错误。但是,我看到的是这样的:

{
  "errorType": "Runtime.ExitError",
  "errorMessage": "RequestId: 48e3b4fb-1b88-48d3-8834-247dbb1a4f3f Error: Runtime exited without providing a reason"
}

日志显示:

{
  "requestId": "b8b91c18-34cd-c5f6-9103-ed3357b9241e",
  "code": "BadRequestException",
  "detailedMessage": "Bad request."
}

查询是(鉴于https://docs.amazonaws.cn/en_us/neptune/latest/userguide/iam-auth-connecting-python.html中描述的 Lambda 代码):

{
  "host": "NAME.cluster-ID.us-east-1.neptune.amazonaws.com:8182",
  "method": "GET",
  "query_type": "status",
  "query": ""
}

有什么建议么?

更新:尝试针对另一个海王星集群,[Errno 111] Connection refused'错误又回来了。然而,我注意到一件奇怪的事情:我有一些孤立的网络接口,从 Lambda 与现已删除的 Neptune 集群的 VPC 相关联开始。但是,网络接口标记为in use,我无法分离和删除它们,即使使用该Force detachment选项也是如此。得到You are not allowed to manage 'ela-attach' attachments错误。

更新:从一个新的 Lambda 开始(不再重做其 VPC 配置,因此不再有孤立的网络接口)和一个启用和配置了 IAM Auth 的新 Neptune 集群(甚至为 Lambda 的执行角色提供了完全管理员访问权限以进行调试,以消除任何丢失的权限),仍然收到此错误:

{
  "errorMessage": "HTTPSConnectionPool(host='NAME.cluster-ID.us-east-1.neptune.amazonaws.com', port=8182): Max retries exceeded with url: /status/ (Caused by NewConnectionError('<urllib3.connection.HTTPSConnection object at 0x7f1f9f98c310>: Failed to establish a new connection: [Errno 111] Connection refused'))",
  "errorType": "ConnectionError",
  "stackTrace": [
    "  File \"/var/task/lambda_function.py\", line 71, in lambda_handler\n    return make_signed_request(host, method, query_type, query)\n",
    "  File \"/var/task/lambda_function.py\", line 264, in make_signed_request\n    r = requests.get(request_url, headers=headers, verify=False, params=request_parameters)\n",
    "  File \"/var/task/requests/api.py\", line 76, in get\n    return request('get', url, params=params, **kwargs)\n",
    "  File \"/var/task/requests/api.py\", line 61, in request\n    return session.request(method=method, url=url, **kwargs)\n",
    "  File \"/var/task/requests/sessions.py\", line 530, in request\n    resp = self.send(prep, **send_kwargs)\n",
    "  File \"/var/task/requests/sessions.py\", line 643, in send\n    r = adapter.send(request, **kwargs)\n",
    "  File \"/var/task/requests/adapters.py\", line 516, in send\n    raise ConnectionError(e, request=request)\n"
  ]
}

标签: amazon-web-servicesaws-lambdaamazon-vpcamazon-neptune

解决方案


需要检查的几件事:

  • 附加到 Neptune 实例的安全组是否允许来自为 Lambda 函数配置的子网的流量?附加到 Neptune 的安全组的默认入站规则是仅允许来自配置它的 IP 地址的流量。

  • NeptuneFullAccess 内置 IAM 策略用于控制平面操作,而不是数据平面操作。您需要使用此处定义的策略文档 [1] 创建一个 IAM 策略,并将该策略附加到您正在使用的任何 Lambda 执行角色。然后,您需要使用该角色来签署向 Neptune 发出的请求。Pythonrequest库不执行 SigV4 签名,因此您需要遵循类似于此处 [2] 中列出的过程。

  • 如果您真的想简化这一切,我们发布了一个 Python 库,可帮助管理连接、IAM 身份验证以及向 Neptune 发送查询。你可以在这里找到它[3]。

[1] https://docs.aws.amazon.com/neptune/latest/userguide/iam-auth.html

[2] https://docs.aws.amazon.com/neptune/latest/userguide/iam-auth-connecting-python.html

[3] https://github.com/awslabs/amazon-neptune-tools/tree/master/neptune-python-utils


推荐阅读