20

I'm writing an application which I want to run as an AWS Lambda function but also adhere to the Twelve-Factor app guidelines. In particular Part III. Config which requires the use of environmental variables for configuration.

However, I cannot find a way to set environmental variables for AWS Lambda instances. Can anyone point me in the right direction?

If it isn't possible to use environmental variables can you please recommend a way to use environmental variables for local development and have them transformed to a valid configuration system that can be accessed using the application code in AWS.

Thanks.

dannybrown
  • 1,083
  • 3
  • 13
  • 26
  • Lambda is not like other functions, there are many restrictions. What exactly are you trying to configure? – helloV Mar 26 '16 at 01:55
  • AWS Credentials, Database details and the like. I could include a config.json file or the like, but I'd much rather stick to twelve-factor style env variables. They make it less likely ill expose a secret to the world via source control. – dannybrown Mar 26 '16 at 01:57

6 Answers6

17

As of November 18, 2016, AWS Lambda supports environment variables.

Environment variables can be specified both using AWS console and AWS CLI. This is how you would create a Lambda with an LD_LIBRARY_PATH environment variable using AWS CLI:

aws lambda create-function \
  --region us-east-1
  --function-name myTestFunction
  --zip-file fileb://path/package.zip
  --role role-arn
  --environment Variables={LD_LIBRARY_PATH=/usr/bin/test/lib64}
  --handler index.handler
  --runtime nodejs4.3
  --profile default
sergio
  • 68,819
  • 11
  • 102
  • 123
  • would like to set the NODE_OPTIONS variable as in here https://nodejs.org/docs/latest-v10.x/api/cli.html#cli_node_options_options to debug an issue but looks only environment variables available are ones in here https://docs.aws.amazon.com/lambda/latest/dg/configuration-envvars.html. Is there a way to set NODE_OPTIONS for the runtime? – Ricardo stands with Ukraine Mar 05 '20 at 12:55
5

Perhaps the 'custom environment variables' feature of node-lambda would address your concerns:

https://www.npmjs.com/package/node-lambda
https://github.com/motdotla/node-lambda

"AWS Lambda doesn't let you set environment variables for your function, but in many cases you will need to configure your function with secure values that you don't want to check into version control, for example a DB connection string or encryption key. Use the sample deploy.env file in combination with the --configFile flag to set values which will be prepended to your compiled Lambda function as process.env environment variables before it gets uploaded to S3."

Tom
  • 17,103
  • 8
  • 67
  • 75
4

There is no way to configure env variables for lambda execution since each invocation is disjoint and no state information is stored. However there are ways to achieve what you want.

AWS credentials - you can avoid storing that in env variables. Instead grant the privileges to your LambdaExec role. In fact, AWS recommends using roles instead of AWS credentials.

Database details: One suggestion is to store it in a well known file in a private bucket. Lambda can download that file when it is invoked, read the contents which can contain database details and other information. Since the bucket is private, others cannot access the file. The LambdaExec role needs IAM privileges to access the private bucket.

helloV
  • 50,176
  • 7
  • 137
  • 145
  • KMS is a better (and recommended?) solution IMHO, there is [a sample here](http://stackoverflow.com/questions/29372278/aws-lambda-how-to-store-secret-to-external-api) – Hang Mar 26 '16 at 02:22
  • 1
    @Hang, yes I forgot to mention KMS. It is a good solution but you are dealing with AWS keys and secrets which I would avoid. You need to maintain the file. IAM roles are easy to revoke compared to credentials stored in a file. – helloV Mar 26 '16 at 02:27
  • 1
    File on S3 is not encrypted, this is my concern. I may be paranoid, but being grilled by infosec, you know. – Hang Mar 26 '16 at 02:30
  • 3
    You can choose server side or client side encryption. I use all the time. http://docs.aws.amazon.com/AmazonS3/latest/dev/UsingEncryption.html – helloV Mar 26 '16 at 02:32
  • 2
    The problem with KMS in relation to this question is that it requires code changes. This code needs to be able to run on non-AWS systems too, and it does so using `process.env`. It's a shame this cannot be achieved on Lambda. – dannybrown Mar 26 '16 at 15:58
2

AWS just added support for configuration of Lambda functions via environment parameters. Take a look here

Froyke
  • 1,115
  • 7
  • 13
1

We also had this requirement for our Lambda function and we "solved" this by generating a env file on our CI platform (in our case this is CircleCI). This file gets included in the archive that gets deployed to Lambda. Now in your code you can include this file and use the variables.

The script that I use to generate a JSON file from CircleCI environment variables is:

cat >dist/env.json <<EOL
{
"CLIENT_ID": "$CLIENT_ID",
"CLIENT_SECRET": "$CLIENT_SECRET",
"SLACK_VERIFICATION_TOKEN": "$SLACK_VERIFICATION_TOKEN",
"BRANCH": "$CIRCLE_BRANCH"
}
EOL

I like this approach because this way you don't have to include environment specific variables in your repository.

Wim Mostmans
  • 3,485
  • 1
  • 20
  • 20
  • 1
    I do something similar to this except I have my CI create a wrapper JavaScript file which populates `process.env` with the environment variables known to the CI. It exports a "pass through" handler function which simply calls `require('./').handler(event, context, done)` to invoke the actual handler. I then write that file to the top-level zip directory as `'${COMMIT_SHA}.js'` and update my lambda function to set the "handler" property to `'${COMMIT_SHA}.handler'`. – idbehold Aug 25 '16 at 17:06
  • @idbehold awesome idea! – Wim Mostmans Aug 26 '16 at 07:30
1

I know it has been a while, but I didn't see a solution that works from the AWS Lambda console.

STEPS:

  1. In your AWS Lambda Function Code, look for "Environment variables", and click on "Edit";
  2. For the "Key", type "LD_LIBRARY_PATH";
  3. For the "Value", type "/opt/python/lib".

Look at this screenshot for the details.

The #3 assumes that you are using Python as your runtime environment, and also that your uploaded Layer has its "lib" folder in the following structure: python/lib

This solution works for the error: /lib/x86_64-linux-gnu/libz.so.1: version 'ZLIB_1.2.9' not found assuming the correct libray file is put in the "lib" folder and that the environment variable is set like above.

PS: If you are unsure about the #3 path, just look for the error in your console, and you will be able to see where your "lib" folder for your layer is at runtime.

Raphael Setin
  • 557
  • 5
  • 10