web-dev-qa-db-fra.com

Comment utiliser AWS Secret Manager avec Nodejs Lambda

J'ai essayé d'envelopper l'exemple d'extrait de code pour obtenir des secrets dans une fonction puis l'appeler, mais il ne semble pas fonctionner. Je soupçonne que je l'appelle asynchrone et je dois l'appeler de manière synchrone? Je veux juste une fonction que je peux appeler pour obtenir une valeur secrète et la mettre dans un var.

c'est la fonction:

//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');
          }
    }
  });
}

Alors je l'appelle

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

Le secret var est toujours undefined

EDIT: ASYNC ne fonctionne que avec des promesses, donc je devais faire ma fonction Async et retourner une promesse:

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')
17
red888

J'ai créé une solution synchrone que vous pouvez trouver ici: https://github.com/jwerre/secrets

Avec cet emballage, vous pouvez charger tous vos secrets à l'intérieur d'un espace de noms particulier comme le cas échéant:

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

Cela récupérera tous vos secrets qui peuvent ne pas être exactement ce que vous voulez. Si vous voulez un seul secret, vous pouvez le faire comme ceci:

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