【问题标题】:how do I use aws secret manager with nodejs lambda如何将 aws 秘密管理器与 nodejs lambda 一起使用
【发布时间】:2019-12-28 07:55:22
【问题描述】:

我试图包装示例代码 sn-p 以在函数中获取机密,然后调用它,但它似乎不起作用。我怀疑我正在异步调用它,我需要同步调用它?我只想要一个可以调用的函数来获取一个秘密值并将其放入一个 var 中。

这是函数:

//outside exports.handler = (event, context, callback) => {
function getSecret(secretName) {
  // Load the AWS SDK
  var AWS = require('aws-sdk'),
      region = process.env.AWS_REGION,
      secretName = secretName,
      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.

  client.getSecretValue({SecretId: secretName}, 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) {
              return data.SecretString;
          } else {
              let buff = new Buffer(data.SecretBinary, 'base64');
              return buff.toString('ascii');
          }
    }
  });
}

那我就叫它

// inside exports.handler = (event, context, callback) => {
var secret = getSecret('mySecret')
console.log('mysecret: ' + secret )

秘密变量总是undefined

编辑:Async 仅适用于 Promise,因此我必须使我的函数异步并返回一个 Promise:

async function mySecrets(secretName) {
    // Load the AWS SDK
    var AWS = require('aws-sdk'),
        region = process.env.AWS_REGION,
        secretName = secretName,
        secret,
        decodedBinarySecret;

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

    return new Promise((resolve,reject)=>{
        client.getSecretValue({SecretId: secretName}, function(err, data) {

            // 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.
            if (err) {
                reject(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) {
                    resolve(data.SecretString);
                } else {
                    let buff = new Buffer(data.SecretBinary, 'base64');
                    resolve(buff.toString('ascii'));
                }
            }
        });
    });
}

.....
// inside handler
exports.handler = async (event) => {
....
var value = await mySecrets('mysecret')

【问题讨论】:

    标签: javascript node.js aws-lambda aws-secrets-manager


    【解决方案1】:

    您需要等待异步调用完成。

    在您的主处理程序中,您将拥有如下内容:

    // inside your main handler
    exports.handler =  async function(event, context) {
        var secret = await getSecret('mySecret')
        console.log('mysecret: ' + secret )
    
        return ...
        }
    

    【讨论】:

    • 我也可以使用 promise 代替吗?
    • 是的,asyc 或承诺相同。
    • @iwaduarte 请您提供完整的异步和等待代码。我可以在哪里动态提供 SecretString 和其他必需的参数
    • 代码完成。如果您需要其他帮助,您应该创建一个新问题并将链接放在此处。
    【解决方案2】:

    我创建了一个同步解决方案,您可以在这里找到:https://github.com/jwerre/secrets

    使用此包,您可以将所有机密加载到特定命名空间中,如下所示:

    const config = require('@jwerre/secrets').configSync({
        region: 'us-east-1',
        env: 'production',
        namespace: 'my-namespace',
    });
    

    这将检索您可能不完全是您想要的所有秘密。如果你想要一个秘密,你可以这样做:

    const config = require('@jwerre/secrets').secretSync({
        region: 'us-west-2'
        id: '/my-co/apis/'
    });
    

    【讨论】:

    • 什么是 /my-co/apis 是秘密名称吗?
    • 确实如此。我将 slashed 用于我的秘密,因此我可以将它们分开以进行不同类型的部署。例如/production/lambda1/mysql/username/staging/api/config/aws/secrete。查看自述文件中的文档。
    【解决方案3】:

    aws-sdk 提供了两种从 API 获取值的方法。您可以使用本机回调机制,如上所示,或者您可以在调用链的末尾使用 .promise(),将 API 调用转换为其等效的 promise。

    例如

    const data = await (secretManager.getSecret({ SecretId }).promise();
    

    如果你使用await,那么你的函数需要像所有调用它的函数一样是async,除非他们选择使用Promise的then/catch等。

    【讨论】:

      【解决方案4】:

      更好的方法是在异步 lambda 函数中执行此操作

      例如key:val => password:rootPassword

      const secret = await secretClient.getSecretValue({SecretId: 'SecretKeyName'}).promise().then((data) => {
              return JSON.parse(data.SecretString);
      })
      

      然后以secret.password 访问它。

      注意:环绕try/catch 块以自动处理错误。

      【讨论】:

        【解决方案5】:

        如果有人需要解决这个问题,这里有一个更简单的例子:

        const result = await client
          .getSecretValue({
            SecretId: AWSConfig.secretName,
          })
          .promise();
        
        const parsedResult = JSON.parse(result.SecretString);
        

        【讨论】:

        • 经过两天无数次尝试来完成这项工作 ==> 成功了!
        • 完美!我认为每个人都会立即寻找更短的方法。
        【解决方案6】:

        还有一种更简单的方法可以从秘密管理器中读取它。

        let secretManager = new SecretsManager({ region: 'region-name' });
        const data = await secretManager.getSecretValue({ SecretId: 'secretid' }).promise();
        console.log(`data is: ${JSON.stringify(data)}`);
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2022-08-16
          • 2020-12-04
          • 1970-01-01
          • 2020-08-16
          • 2020-10-01
          • 1970-01-01
          • 2021-03-15
          • 2020-10-13
          相关资源
          最近更新 更多