Using Secret Manager With Serverless Framework
2 min readJun 29, 2024
Step 1:Launch an EC2 instance using Amazon Linux 2 AMI and install node18 and serverless framework using following commands:
sudo su -
### download the NodeJS binary (x86 only)
wget -nv https://d3rnber7ry90et.cloudfront.net/linux-x86_64/node-v18.17.1.tar.gz
mkdir /usr/local/lib/node
tar -xf node-v18.17.1.tar.gz
mv node-v18.17.1 /usr/local/lib/node/nodejs
### Unload NVM, use the new node in the path, then install some items globally.
echo "export NVM_DIR=''" >> /home/ec2-user/.bashrc
echo "export NODEJS_HOME=/usr/local/lib/node/nodejs" >> /home/ec2-user/.bashrc
echo "export PATH=\$NODEJS_HOME/bin:\$PATH" >> /home/ec2-user/.bashrc
### Reload environment
. /home/ec2-user/.bashrc
#Verify NodeJS v18.x is operating
node -e "console.log('Running Node.js ' + process.version)"
npm install -g serverless@3
Step 2: Create 2 secrets named sampleApp/production and sampleApp/development and store a plaintext value.
Step 3: Now create a serverless project by running following commands:
mkdir test && cd test
npm install aws-sdk
Create a file named handler.js with following code:
'use strict';
const AWS = require('aws-sdk');
const secretsManager = new AWS.SecretsManager();
module.exports.hello = async (event) => {
const secretName = process.env.SECRET_ID;
let secretValue;
try {
const data = await secretsManager.getSecretValue({ SecretId: secretName }).promise();
if ('SecretString' in data) {
secretValue = data.SecretString;
} else {
let buff = Buffer.from(data.SecretBinary, 'base64');
secretValue = buff.toString('ascii');
}
} catch (err) {
console.log(err);
throw err;
}
return {
statusCode: 200,
body: JSON.stringify(
{
message: 'Secret fetched successfully',
secret: secretValue,
},
null,
2
),
};
};
and serverless.yml with following configuration
service: secretmanager
frameworkVersion: '3'
provider:
name: aws
runtime: nodejs18.x
region: us-east-1
iamRoleStatements:
- Effect: "Allow"
Action:
- "secretsmanager:GetSecretValue"
Resource:
- "arn:aws:secretsmanager:${self:provider.region}:${aws:accountId}:secret:sampleApp/production*"
- "arn:aws:secretsmanager:${self:provider.region}:${aws:accountId}:secret:sampleApp/development*"
environment:
SECRET_ID: sampleApp/${opt:stage, 'development'}
functions:
hello:
handler: handler.hello
environment:
SECRET_VALUE: ${ssm:${self:custom.secrets.SECRET_ID}}
custom:
secrets:
SECRET_ID: /aws/reference/secretsmanager/sampleApp/${opt:stage, 'development'}
Here 2 environment variables will be added to Lambda function
ENVIRONMENT_VARIABLE_NAME ENVIRONMENT_VARIABLE_VALUE
SECRET_ID Name of the secret
SECRET_VALUE Value stored in the secret
Step 4: Deploy serverless resources using following commands
serverless deploy --stage development
serverless deploy --stage production
and trigger the lambda functions