You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过AWS SAM实现Lambda与Mongo Atlas Serverless的IAM角色连通

从AWS视角实现Lambda与MongoDB Atlas无密码认证的完整流程

核心概念澄清

你混淆了两个关键IAM角色:

  1. Atlas扮演角色:MongoDB Atlas用来验证AWS身份的角色,信任策略需允许MongoDB的AWS账号扮演
  2. Lambda执行角色:Lambda运行时使用的角色,信任策略必须允许AWS Lambda服务扮演,同时需具备扮演Atlas角色的权限

步骤1:创建Atlas专用的IAM扮演角色

这个角色用于MongoDB Atlas验证你的AWS身份,信任策略配置为允许指定的MongoDB AWS账号扮演,同时绑定Atlas控制台生成的External ID:

MongoDBAtlasAssumeRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: MongoDBAtlasAssumeRole
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              AWS: arn:aws:iam::<Atlas_AWS_Account_ID>:root
            Action: sts:AssumeRole
            Condition:
              StringEquals:
                sts:ExternalId: <你的Atlas配置的External_ID>
      # 无需额外权限,仅用于身份验证

步骤2:创建Lambda执行角色

这个角色是Lambda运行时的身份,必须允许Lambda服务扮演,同时添加权限让它能调用sts:AssumeRole获取Atlas角色的临时凭证:

LambdaMongoDBExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: LambdaMongoDBExecutionRole
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service: lambda.amazonaws.com
            Action: sts:AssumeRole
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole # 日志权限,必填
      Policies:
        - PolicyName: AllowAssumeMongoDBRole
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action: sts:AssumeRole
                Resource: !GetAtt MongoDBAtlasAssumeRole.Arn

步骤3:绑定Lambda与执行角色

在SAM模板中给Lambda指定上面创建的执行角色,而非Atlas扮演角色:

StepPlanCRUD:
    Type: AWS::Serverless::Function
    Properties:
      PackageType: Image
      Architectures:
        - x86_64
      Role: !GetAtt LambdaMongoDBExecutionRole.Arn

步骤4:修正Lambda代码逻辑

不要直接使用Lambda默认的临时凭证,需主动扮演Atlas角色获取专用凭证后再连接MongoDB:

import boto3
import os
from pymongo import MongoClient

def lambda_handler(event, context):
    # 初始化STS客户端
    sts_client = boto3.client('sts')
    
    # 扮演Atlas专用角色
    assumed_role = sts_client.assume_role(
        RoleArn=os.getenv("MONGODB_ATLAS_ROLE_ARN"), # 配置为Lambda环境变量
        RoleSessionName="LambdaMongoDBAtlasSession",
        ExternalId=os.getenv("MONGODB_ATLAS_EXTERNAL_ID") # 配置为Lambda环境变量
    )
    
    # 提取临时凭证
    access_key = assumed_role['Credentials']['AccessKeyId']
    secret_key = assumed_role['Credentials']['SecretAccessKey']
    session_token = assumed_role['Credentials']['SessionToken']
    
    # 生成MongoDB连接串
    server_name = os.getenv("MONGODB_SERVER_NAME")
    url_connection = f"mongodb+srv://{access_key}:{secret_key}@{server_name}.ozmat.mongodb.net/?authSource=%24external&authMechanism=MONGODB-AWS&retryWrites=true&w=majority&authMechanismProperties=AWS_SESSION_TOKEN:{session_token}"
    
    # 建立连接并执行操作
    client = MongoClient(url_connection)
    # 后续业务逻辑...

步骤5:配置Lambda环境变量

在SAM模板或Lambda控制台添加以下环境变量:

  • MONGODB_ATLAS_ROLE_ARN:步骤1创建的MongoDBAtlasAssumeRole的ARN
  • MONGODB_ATLAS_EXTERNAL_ID:Atlas控制台生成的External ID
  • MONGODB_SERVER_NAME:你的MongoDB Atlas集群服务器前缀

你之前的错误分析

  1. 角色信任策略错误:将Lambda执行角色的信任策略配置为允许MongoDB账号扮演,导致Lambda无法假设该角色,触发The role defined for the function cannot be assumed by Lambda错误
  2. 凭证使用错误:直接使用Lambda默认执行凭证而非Atlas专用角色凭证,导致Atlas识别到的是Lambda默认角色ARN,而非你在Atlas配置的角色,触发user arn:aws:sts::...:assumed-role/<incorrect_role_name> is not found错误

内容的提问来源于stack exchange,提问作者user12672705

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 19:45:43