One of the most burning question i've come across while working in Serverless Architecture is "What's the right way to manage secrets in serverless applications?". The question might have many answers like hard-coding into the application, storing them as .env variables or using dedicated secret files.
But all of them requires you to write the secrets in the file you're working with, the files you might unknowingly push to GitHub. So is there no any better way ? The answer is: There is !! Using Parameter Store provided under AWS SSM. We will be using aws-cli/aws-console, aws-sdk with NodeJS to store and retrieve a MongoDB connection String.
Parameter store allows us to create different type of secrets like String type Key-Value Pair, StringList type Key-value pair. We will be using simple String type in our case as mongoDB connection string is just a normal String in the below format so just a simple key-value pair will do the trick.
mongodb+srv://user:password@mycluster-nqdzq.mongodb.net/dbname
Now, its to time create our Secret. In order to create the Secret, we will be using AWS Console. So Go to AWS Console, and search for SSM, There will be a pop-up with Systems Manager , click on that and you'll be forwarded to SSM main page. Now on the left side, you'll find the Parameter Store. After clicking on that, there will be an option called Create parameter if you don't have any Secrets stored YET, if you already have any Secretes created, you'll be presented with the list along with Create Parameter Option, click on Create Parameter.
After clicking on Create Parameter, you'll be presented with a screen similar to :
Now, its time to fill up the values. Give it a suitable name, in my case i'll write NOTEAPP_CONN_STRING. Descriptions are optional, you can leave that blank, Choose Standard Tier and String in Type and paste the Mongo Connection String. You can also give it some tags which is totally optional, so you can just hit Create Parameter.
Now, its time to Access it through our Lamda Function. In order to access the Parameter Store, we first have to provide some IAM permissions. Inside you .yml file under Provider Section in iamRoleStatements Section, copy/paste the following policies:
iamRoleStatements:
- Effect: Allow
Action:
- "ssm:GetParameter*"
Resource: "*"
Now, inside our handler function, what we will do is, we will simple console log the secret however you can do anything you want once you have the access. So our handler file will look something like this :
const AWS = require("aws-sdk");
const ssm = new AWS.SSM();
let param = {
Name: "NOTEAPP_CONN_STRING", // Our Secret Name
WithDecryption: true,
};
module.exports.handler = async (event) => {
let request = await ssm.getParameter(param).promise();
let conn_string = request.Parameter.Value;
console.log(conn_string);
}
So we see that there is no trace of our Secret in our Code but it is stored in AWS. This is how you manage the secrets in Serverless applications