AWS Lambda跨账号访问DynamoDB报错:无法读取undefined的'send'属性
解决AWS Lambda ESM(.mjs)跨账号访问DynamoDB的TypeError问题
错误根源
TypeError: Cannot read properties of undefined (reading 'send') 本质是STS客户端实例未正确初始化,核心原因是ESM(.mjs)模块的导入/导出逻辑和CommonJS(.js)不兼容,比如误用CommonJS的require语法,导致SDK客户端对象加载失败。
基于正常CommonJS代码的ESM转换方案
假设你能正常运行的CommonJS代码结构如下:
const { STSClient, AssumeRoleCommand } = require("@aws-sdk/client-sts"); const { DynamoDBClient, ScanCommand } = require("@aws-sdk/client-dynamodb"); exports.handler = async (event) => { const stsClient = new STSClient({ region: "us-east-1" }); const assumeRoleParams = { RoleArn: "arn:aws:iam::目标账号ID:role/跨账号访问角色名", RoleSessionName: "CrossAccountSession" }; const assumeRoleResponse = await stsClient.send(new AssumeRoleCommand(assumeRoleParams)); const credentials = assumeRoleResponse.Credentials; const dynamoClient = new DynamoDBClient({ region: "us-east-1", credentials: { accessKeyId: credentials.AccessKeyId, secretAccessKey: credentials.SecretAccessKey, sessionToken: credentials.SessionToken } }); const scanParams = { TableName: "目标表名" }; const scanResponse = await dynamoClient.send(new ScanCommand(scanParams)); return { statusCode: 200, body: JSON.stringify(scanResponse.Items) }; };
转换成可正常运行的.mjs代码,需修改3个核心点:
- 用
import替代require - 用
export const handler替代exports.handler - 保留SDK客户端的初始化逻辑
正确的.mjs代码示例
import { STSClient, AssumeRoleCommand } from "@aws-sdk/client-sts"; import { DynamoDBClient, ScanCommand } from "@aws-sdk/client-dynamodb"; export const handler = async (event) => { // 初始化STS客户端 const stsClient = new STSClient({ region: "us-east-1" }); const assumeRoleParams = { RoleArn: "arn:aws:iam::目标账号ID:role/跨账号访问角色名", RoleSessionName: "CrossAccountSession" // 自定义唯一会话名称 }; try { // 获取跨账号临时凭证 const assumeRoleResponse = await stsClient.send(new AssumeRoleCommand(assumeRoleParams)); const credentials = assumeRoleResponse.Credentials; // 用临时凭证初始化DynamoDB客户端 const dynamoClient = new DynamoDBClient({ region: "us-east-1", credentials: { accessKeyId: credentials.AccessKeyId, secretAccessKey: credentials.SecretAccessKey, sessionToken: credentials.SessionToken } }); // 执行DynamoDB操作(示例为Scan) const scanParams = { TableName: "目标表名" }; const scanResponse = await dynamoClient.send(new ScanCommand(scanParams)); return { statusCode: 200, body: JSON.stringify(scanResponse.Items) }; } catch (error) { console.error("执行错误:", error); return { statusCode: 500, body: JSON.stringify({ error: error.message }) }; } };
关键注意事项
- 模块语法严格区分:ESM必须全程使用
import/export,禁止混用require,否则会导致客户端实例加载为undefined。 - Lambda运行时版本:确保函数配置的Node.js版本为14.x及以上(Node.js 13.2+原生支持ESM)。
- 权限校验:
- 当前Lambda的执行角色需拥有
sts:AssumeRole权限 - 目标账号的跨账号角色,其信任策略需允许当前Lambda执行角色的ARN访问
- 当前Lambda的执行角色需拥有
- 错误捕获:添加
try/catch可快速定位权限错误、ARN拼写错误等问题。
排查步骤(若仍报错)
- 打印STS客户端实例:在
new STSClient后添加console.log(stsClient),确认对象不为undefined - 检查依赖安装:确认
@aws-sdk/client-sts和@aws-sdk/client-dynamodb已正确安装 - 验证角色配置:手动测试AssumeRole命令,确认跨账号角色的信任策略和权限配置无误
内容的提问来源于stack exchange,提问作者Michio ghe
相关产品推荐
相关产品推荐

