Skip to content

Instantly share code, notes, and snippets.

@amancevice
Last active April 16, 2021 21:36
Show Gist options
  • Save amancevice/4f1444fe8f59b29533d0ccf23d29787a to your computer and use it in GitHub Desktop.
Save amancevice/4f1444fe8f59b29533d0ccf23d29787a to your computer and use it in GitHub Desktop.

Managing ENV with AWS SecretsManager for NodeJS

AWS SecretsManager is a service that allows you to store encrypted secrets in the cloud as raw strings or JSON docs.

Storing secrets as JSON allows you to store ENV settings, similar to a .env file.

Using the aws-sdk library for NodeJS, we can update our application's process.env with the encrypted environment.

Install AWS SDK

npm install aws-sdk

Updating ENV Asynchronously

Using the promise-ified version of the getSecretValue() function, we can update the process.env object with the response of the AWS resource.

'use strict';
const AWS            = require('aws-sdk');
const AWS_SECRET     = process.env.AWS_SECRET;
const secretsmanager = new AWS.SecretsManager();

secretsmanager.getSecretValue({SecretId: AWS_SECRET}).promise().then((res) => {
  Object.assign(process.env, JSON.parse(res.SecretString));
  return process.env;
});

Using With Serverless Express

When deploying express apps to AWS Lambda you can establish your ENV before handling the HTTP request.

'use strict';
const AWS                  = require('aws-sdk');
const awsServerlessExpress = require('aws-serverless-express');
const secretsmanager       = new AWS.SecretsManager();
const AWS_SECRET           = process.env.AWS_SECRET;

let server;

const createServer = async (options) => {
  // Get AWS secret JSON string
  const secret = await secretsmanager.getSecretValue(options).promise();

  // Update ENV
  Object.assign(process.env, JSON.parse(secret.SecretString));

  // Import express app & create server
  server = awsServerlessExpress.createServer(require('./app'));
  return server;
}

// Export Lambda handler
exports.handler = (event, context) => {
  Promise.resolve(server || createServer({SecretId: AWS_SECRET})).then((server) => {
    awsServerlessExpress.proxy(server, event, context)
  });
};
@BinaryPhinary
Copy link

Hi - I dont know if anyone is still watching this thread - however I've used the above and while it does grab the secret - I can no longer create an async function within the export handler. In this case I need to create an async function to cache a MongoDB custom connect string. Any thoughts on that?

@amancevice
Copy link
Author

amancevice commented Aug 20, 2020

can you paste a code example?

I think you should be able to do something like:

// Export Lambda handler
exports.handler = async (event, context) => {
  await Promise.resolve(server || createServer({SecretId: AWS_SECRET}));
  return await awsServerlessExpress.proxy(server, event, context, 'PROMISE').promise;
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment