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

AWS Lambda(NodeJS)获取Secrets Manager密钥无响应问题

问题成因

核心问题是混用了两套不兼容的AWS SDK异步调用逻辑:

  • 你将handler声明为async异步函数,给getSecretValue加了await的同时,又传入了传统回调函数作为入参
  • AWS JavaScript SDK v2的规则是:调用API方法时只要传入了回调,方法就不会返回Promise对象
  • 这种写法下await实际等待的是undefined,完全不会阻塞等待API请求返回。Lambda打印完SDK版本后就会直接走完函数执行流程、冻结运行环境,传入的回调根本没机会被触发,自然看不到回调里的任何日志输出。
修复方案

两种写法二选一即可,绝对不要同时混用回调和async/await模式:

方案1:async/await 写法(官方推荐)

去掉getSecretValue的回调入参,直接等待API返回的Promise,用try/catch统一捕获错误即可,修正后的可运行代码:

const aws = require("aws-sdk");

exports.handler = async (event) => {
    console.log("version = " + aws.VERSION)

    const client = new aws.SecretsManager({
        version: '2017-10-17',
        region: 'eu-west-2'
    });
    let secret, decodedBinarySecret;

    try {
        // 不传回调时,显式调用.promise()是最稳妥的写法,兼容所有v2版本SDK
        const data = await client.getSecretValue({
            SecretId: 'mysecretid'
        }).promise();
        
        console.log("I am here 1");
        // Secrets Manager存储的RDS凭证默认是JSON字符串,直接解析即可拿到用户名、密码、端口等字段
        if ('SecretString' in data) {
            secret = JSON.parse(data.SecretString);
        } else {
            let buff = Buffer.from(data.SecretBinary, 'base64');
            decodedBinarySecret = buff.toString('ascii');
        }

        console.log("I am here 3");
        console.log(secret);
        // 后续直接用解析后的密钥信息连接RDS即可
        return { statusCode: 200, body: 'Secret retrieved successfully' };
    } catch (err) {
        console.log("I am here 2");
        const errorCodes = [
            'DecryptionFailureException',
            'InternalServiceErrorException',
            'InvalidParameterException',
            'InvalidRequestException',
            'ResourceNotFoundException'
        ];
        if (errorCodes.includes(err.code)) {
            console.error(`Request failed with code ${err.code}: ${err.message}`);
        }
        throw err;
    }
};

方案2:传统回调写法(不推荐)

如果要保留回调逻辑,需要去掉handler的async声明,在回调执行完成后手动调用Lambda内置的callback方法通知函数执行结束,否则函数还是会提前退出:

const aws = require("aws-sdk");

// 去掉async,接收Lambda注入的context、callback参数
exports.handler = (event, context, callback) => {
    console.log("version = " + aws.VERSION)

    const client = new aws.SecretsManager({
        version: '2017-10-17',
        region: 'eu-west-2'
    });
    let secret, decodedBinarySecret;

    client.getSecretValue({
        SecretId: 'mysecretid'
    }, function(err, data) {
        if (err) {
            console.log("I am here 2");
            // 原有错误处理逻辑
            callback(err);
            return;
        }

        console.log("I am here 1");
        if ('SecretString' in data) {
            secret = data.SecretString;
        } else {
            // 注意:new Buffer()已被Node.js标记为废弃,统一使用Buffer.from()
            let buff = Buffer.from(data.SecretBinary, 'base64');
            decodedBinarySecret = buff.toString('ascii');
        }

        console.log("I am here 3");
        console.log(secret);
        // 所有逻辑执行完成后必须调用callback返回结果,否则函数会卡住直到超时
        callback(null, { statusCode: 200, body: 'success' });
    });
};

额外提示:你原有代码里使用的new Buffer()构造方法已经在Node.js 8之后的版本被标记为废弃,存在安全隐患,统一替换为Buffer.from()即可消除运行时警告。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 22:33:22