使用 IAM 从 AWS lambda python 连接 mongodb

问题描述 投票:0回答:2

到目前为止,我一直在使用

pymongo[srv]
将我的 AWS lambda 连接到我的 MongoDB 集群:

mongodb+srv://username:[email protected]/database

现在我正在尝试设置 IAM 角色connection,在这个repo中有一个连接字符串,例如:

"mongodb://<access_key>:<secret_key>@mongodb.example.com/?authMechanism=MONGODB-AWS&authMechanismProperties=AWS_SESSION_TOKEN:<security_token>"

我已经尝试过这个,但我的 Cloudwatch 日志中出现以下错误:

[ERROR] ValueError: Port must be an integer between 0 and 65535: 'Fizjqbxairn6K19Fsalbucyz'
Traceback (most recent call last):
  File "/var/lang/lib/python3.9/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1030, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
  File "<frozen importlib._bootstrap>", line 986, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 680, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 850, in exec_module
  File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed
  File "/var/task/lambda_function.py", line 13, in <module>
    client = MongoClient(
  File "/var/task/pymongo/mongo_client.py", line 736, in __init__
    res = uri_parser.parse_uri(
  File "/var/task/pymongo/uri_parser.py", line 568, in parse_uri
    nodes = split_hosts(hosts, default_port=default_port)
  File "/var/task/pymongo/uri_parser.py", line 376, in split_hosts
    nodes.append(parse_host(entity, port))
  File "/var/task/pymongo/uri_parser.py", line 137, in parse_host
    raise ValueError("Port must be an integer between 0 and 65535: %r" % (port,))

所以我猜测字符串语法不正确。

请告诉我使用

AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY 
环境变量时使用的正确连接字符串是什么:

client = MongoClient(conn_string)

编辑

我的Python字符串是:

client = MongoClient('mongodb://' + os.environ.get("AWS_ACCESS_KEY_ID") + ':' + os.environ.get("AWS_SECRET_ACCESS_KEY") + @clustername/databasename?retryWrites=true&authMechanism=MONGODB-AWS)

我正在安装

pymongo[aws]
作为依赖项而不是
pymongo[srv]

编辑2

我确认

AWS_SECRET_ACCESS_KEY
包含
/
作为字符。

编辑3

上述错误不再相关,

pymongo
接受编码的连接字符串,但这不是根据此文档使用AWS Lambda的好方法。

我正在尝试使用

pymongo[aws]
将我的 AWS Lambda 连接到我的 Atlas 集群数据库,但它总是超时。

根据上述文档,URI 应如下所示:

uri = "mongodb://example.com/?authMechanism=MONGODB-AWS"

我当然已经尝试过,并且没有更多错误或任何东西,lambda 只是超时了。

当我创建数据库用户时,我仔细检查了 lambda 的

ARN
角色以及 MongoDB 中的设置。

我还授予了

dbAdmin
角色,以确保这不是权限问题,但仍然超时。

MongoDB 社区支持也试图在这个案例上提供帮助。

有什么想法可以从哪里来吗?

mongodb aws-lambda pymongo mongodb-atlas
2个回答
2
投票

有 3 个移动部件应配置为协同工作:

  1. python 代码/库
  2. AWS Lambda 角色和 VPC
  3. Atlas 网络和数据库访问

蟒蛇

pip install "pymongo[aws]"

开始

在回答时,它提取了以下依赖项:

boto3==1.26.121
botocore==1.29.121
dnspython==2.3.0
jmespath==1.0.1
pymongo==4.3.3
pymongo-auth-aws==1.1.0
python-dateutil==2.8.2
s3transfer==0.6.0
six==1.16.0
urllib3==1.26.15

要测试的最小 lambda 代码:

from pymongo.mongo_client import MongoClient
from pymongo.server_api import ServerApi


def lambda_handler(event, context):

    uri = "mongodb+srv://<cluster_name>.<subdomain>.mongodb.net/?authSource=%24external&authMechanism=MONGODB-AWS&retryWrites=true&w=majority"
    # Create a new client and connect to the server
    client = MongoClient(uri, server_api=ServerApi('1'))
    # Send a ping to confirm a successful connection
    try:
        client.admin.command('ping')
        print("Pinged your deployment. You successfully connected to MongoDB!")
    except Exception as e:
        print(e)

uri
中的集群名称和域名可以在Atlas连接设置中找到。在屏幕截图上,它是 python 驱动程序,但无论客户端如何,域都是相同的:

注意: pymongo-auth-aws 与 AWS 环境变量配合良好,因此无需在

uri

中显式设置它们

AWS Lambda 和 Mongodb Atlas

网络接入

该功能应该部署在VPC内,让VPC与Atlas对等,或者至少有一个固定的出口IP,允许从该IP(下图中蓝色圈出的部分)网络连接到Atlas。为了进行实验 - 暂时允许从任何位置 0.0.0.0/0 访问 Atlas 以隔离调试身份验证。 在应用程序层连接后,返回网络配置。即使在开发环境中也不要将其打开

数据库访问:

认证是基于角色名的,所以需要复制 lambda 执行角色的准确 ARN,在 Atlas 端创建用户,粘贴角色名,并为用户分配 mongodb 级别权限(下图中红色路径) ).

测试:

配置完成后,您可以手动触发该功能(payload无关紧要,它没有被使用),并观察日志中的

Pinged your deployment. You successfully connected to MongoDB!


1
投票

我认为您应该转义 userName/password/sessionToken (AWS_*) 中的值,搜索 aws here。换句话说,您在连接字符串中提供的所有值以及可能包含特殊字符(例如

:
/
)的值都应该被转义。请参阅这个SO问题,了解如何在Python中完成它

© www.soinside.com 2019 - 2024. All rights reserved.