使用JS从AWS Lambda访问AWS Secrets Manager密钥

时间:2020-07-06 08:55:23

标签: javascript amazon-web-services promise aws-lambda aws-secrets-manager

我在AWS Secrets Manager中创建了一个机密。尝试从AWS Secret Manager页面获得的示例代码不会产生任何结果。 下面是示例代码 dumbly 复制到JavaScript AWS Lambda函数中。

为了使其正常工作,我必须在开头添加await,并在API调用中添加.promise()

instruction on AWS Promises之后,我只需要添加awaitpromise()而不是使用回调函数:

AWS.Request.promise方法提供了一种调用服务操作和管理异步流的方法,而不是使用回调

问题:该示例代码已经包含一个回调,为什么我需要添加awaitprommise?我想念什么?


AWS Lambda函数代码示例:

exports.handler = async function(event, context, callback) {
    // Use this code snippet in your app.
    // If you need more information about configurations or implementing the sample code, visit the AWS docs:
    // https://aws.amazon.com/developers/getting-started/nodejs/

    // Load the AWS SDK
    var AWS = require('aws-sdk'),
        region = "eu-west-1",
        secretName = "MY_SUPER_SECRET",
        secret,
        decodedBinarySecret;

    // Create a Secrets Manager client
    var client = new AWS.SecretsManager({
        region: region
    });

    // In this sample we only handle the specific exceptions for the 'GetSecretValue' API.
    // See https://docs.aws.amazon.com/secretsmanager/latest/apireference/API_GetSecretValue.html
    // We rethrow the exception by default.

    // ---> THIS await IS NEEDED TO MAKE IT WORK TOGETHER WITH THE promise() AT THE END
    await client.getSecretValue({SecretId: "MY_SUPER_SECRET"}, function(err, data) {
        if (err) {
            if (err.code === 'DecryptionFailureException')
                // Secrets Manager can't decrypt the protected secret text using the provided KMS key.
                // Deal with the exception here, and/or rethrow at your discretion.
                throw err;
            else if (err.code === 'InternalServiceErrorException')
                // An error occurred on the server side.
                // Deal with the exception here, and/or rethrow at your discretion.
                throw err;
            else if (err.code === 'InvalidParameterException')
                // You provided an invalid value for a parameter.
                // Deal with the exception here, and/or rethrow at your discretion.
                throw err;
            else if (err.code === 'InvalidRequestException')
                // You provided a parameter value that is not valid for the current state of the resource.
                // Deal with the exception here, and/or rethrow at your discretion.
                throw err;
            else if (err.code === 'ResourceNotFoundException')
                // We can't find the resource that you asked for.
                // Deal with the exception here, and/or rethrow at your discretion.
                throw err;
        }
        else {
            // Decrypts secret using the associated KMS CMK.
            // Depending on whether the secret is a string or binary, one of these fields will be populated.
            if ('SecretString' in data) {
                secret = data.SecretString;
                console.warn("secret")
                console.warn(secret)
            } else {
                let buff = new Buffer(data.SecretBinary, 'base64');
                decodedBinarySecret = buff.toString('ascii');
                console.warn("decodedBinarySecret")
                console.warn(decodedBinarySecret)
            }
        }
    
    // Your code goes here. 

    // ---> THIS promise IS NEEDED TO MAKE IT WORK TOGETHER WITH THE await AT THE BEGINING
    }).promise();
)    

1 个答案:

答案 0 :(得分:1)

如果在aws调用中使用.promise(),则不应向其传递回调(有关更多详细信息,请参见this)。取而代之的是,您会在实现此承诺后处理响应(或错误)。

我将其重写为:

function getAwsSecretPromise() {
    return client.getSecretValue({
        SecretId: "MY_SUPER_SECRET"
    }).promise();
}

const rethrowErrorCodes = ['DecryptionFailureException', 'InternalServiceErrorException', 'InvalidParameterException', 'InvalidRequestException', 'ResourceNotFoundException']

exports.handler = async function (event, context, callback) {

    try {
        const data = await getAwsSecretPromise();
        if ('SecretString' in data) {
            secret = data.SecretString;
            console.warn("secret")
            console.warn(secret)
        } else {
            let buff = new Buffer(data.SecretBinary, 'base64');
            decodedBinarySecret = buff.toString('ascii');
            console.warn("decodedBinarySecret")
            console.warn(decodedBinarySecret)
        }

      // todo: do something with secret?
    } catch (err) {
        if (rethrowErrorCodes.some(errorCode => err.code === errorCode) {
            throw err;
        }            
        // todo: handle other errors?    
    }