John Davis
John Davis

Reputation: 23

Using serverless, how to add secret keys as environment variable in AWS lambda function?

I need to deploy AWS lambda function using serverless with secret keys into environment variable from a file. I do not want to use AWS secret/system manager. How do I hide the environment variable in serverless.yml file?

When i manually upload and deploy my nodejs AWS lambda function, it is able to read data from environment variable and run. I want to handle this using serverless instead of manual deployment.

My serverless yml file is as below:

service: sample-lambda

provider:
  name: aws
  runtime: nodejs10.x

  stage: dev
  region: us-east-2
  apiName: getData
  profile: MYAWS
  timeout: 300
  memorySize: 512

functions:
  getData:
    handler: handler.getData
    name: getData
    description:  API to get data from server
    environment:
      key1: 12345
      key2: abcdef
      server: sample

    events:
     - http:  
         path: getData
         method: post
         cors: true

Upvotes: 2

Views: 3100

Answers (2)

Keith Harris
Keith Harris

Reputation: 1148

As an alternative to the accepted answer, and if you're like me and don't like to tinker with extra secret files, you can also use AWS Systems Manager Parameter Store service. You can store your Amazon Keys, Database connections, username, and passwords.

The advantage of this approach is that you save your keys once and use them on many projects as long as they are created in the same region.

To save your environment variables in AWS Parameter Store using the AWS cli line:

aws --profile default --region us-west-2 ssm put-parameter --name KEY1 --value 123456 --type String

aws --profile default --region us-west-2 ssm put-parameter --name KEY2 --value abcdef --type String

aws --profile default --region us-west-2 ssm put-parameter --name SERVER --value sample --type String

To save your environment variables in AWS Parameter Store using the Console:

  1. Login to AWS Console.
  2. Search for Systems Manager.
  3. Under Application Management, look for Parameter Store.
  4. Click Create parameter button.

To use the keys in your serverless.yml file:

service: sample-lambda-service

custom:
  config:
    KEY1: ${ssm:KEY1}
    KEY2: ${ssm:KEY2}
    SERVER: ${ssm:SERVER}

provider:
  name: aws
  stage: prod
  timeout: 20
  memorySize: 512
  region: us-west-2
  runtime: nodejs12.x
  endpointType: regional
  environment: ${self:custom.config}
. . .

Then you can use them in your handler.js file as normal environment variables like this:

'use strict'

const AWS = require("aws-sdk");
const s3 = new AWS.S3({
  credentials: {
    accessKeyId: process.env.KEY1,
    secretAccessKey: process.env.KEY2,
  },
});
let server = process.env.SERVER;
. . .

Upvotes: 6

Karthik
Karthik

Reputation: 222

Use serverless-secrets-plugin package from npm and install it.

You can create different files for different environment. When your stage is dev, use file secrets.dev.yml When your stage is production, use file secrets.production.yml

Create a file secrets.dev.yml and add data as below:

key1: 123456
key2: abcdef
server: sample

To encrypt your secrets.dev.yml file with password:

serverless encrypt --stage dev --password 'YOUR_PASSWORD'

To decrypt your secrets.dev.yml file with password:

serverless encrypt --stage dev --password 'YOUR_PASSWORD'

Note: Before deploying the lambda function, make sure that secrets.dev.yml file is in decrypted view

Update serverless.yml as below:

service: sample-lambda

plugins:
  - serverless-secrets-plugin

custom:
  secrets: ${file(secrets.${opt:stage, self:provider.stage}.yml)}

provider:
  name: aws
  runtime: nodejs10.x

  stage: dev
  region: us-east-2
  apiName: getData
  profile: MYAWS
  timeout: 300
  memorySize: 512

functions:
  getData:
    handler: handler.getData
    name: getData
    description:  API to get data from server
    environment:
      key1: ${self:custom.secrets.key1}
      key2: ${self:custom.secrets.key2}
      server: ${self:custom.secrets.server}

    events:
     - http:  
         path: getData
         method: post
         cors: true

Upvotes: 2

Related Questions