Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AWS Lambda@Edge Nodejs "Environment variables are not supported."

Motivation for doing this approach in the first place comes from Amazon: https://aws.amazon.com/blogs/compute/resize-images-on-the-fly-with-amazon-s3-aws-lambda-and-amazon-api-gateway/ (before they added the 'update'...)

In our AWS Lambda resize function it resizes the image and stores it the new image on S3.

const s3_bucket = process.env.s3_bucket;
S3.putObject({
  Body: buffer,
  Bucket: s3_bucket,
  ContentType: contentType,
  CacheControl: 'max-age=31536000',
  Key: key,
  StorageClass: 'STANDARD'
}).promise()

Now we want this to work for all our test/staging environments as well as production.. So I found "Environment Variables", I though great! But when I try to deploy a new version all I get is:

Environment variables not supported

Have we set up something incorrectly in CloudFront? We are using Node version 6.10. I find it hard to believe if we have to hardcode the buckets and keep different versions of the code just to handle this? If that is the case then we wasted a lot of time using AWS Lambda...

Edit: What we do is take a request for an image like "media/catalog/product/3/0/30123/768x/lorem.jpg", then we use the original image located at "media/catalog/product/3/0/30123.jpg", resize it to 768px and webp if the browser supports that and then return the new image (if not already cached).

like image 602
OZZIE Avatar asked Feb 22 '19 14:02

OZZIE


People also ask

Can Lambda edge have environment variables?

With Lambda@Edge we not allow to use environment variables.

Does AWS Lambda support environment variables?

You can now set environment variables for your Lambda functions, making it easy for you to configure your code for development, test, and production without having to change the function's implementation.

Does AWS Lambda support node JS?

AWS Lambda now supports Node. js 16 as both a managed runtime and a container base image. Developers creating serverless applications in Lambda with Node. js 16 can take advantage of new features such as support for Apple silicon for local development, the timers promises API, and enhanced performance.


2 Answers

Workaround using custom origin headers

Environment variables are not supported by Lambda@Edge as specified in the limitations documentation.

But if you are using Lambda@Edge either on origin request or origin response, you can use a workaround with CloudFront Origin Custom Headers.

Basically instead of environment variable, you can set custom headers within your CloudFront origin. Those "static" headers will then be passed to your origin request/response Lambda@Edge.

enter image description here

Then you can access them in your Lambda@Edge function code via:

const foo = request.origin.custom.customHeaders["x-env-foo"][0].value;

Or when using S3 as the origin:

const foo = request.origin.s3.customHeaders["x-env-foo"][0].value;

See also https://medium.com/@mnylen/lambda-edge-gotchas-and-tips-93083f8b4152

like image 127
Yves M. Avatar answered Oct 04 '22 01:10

Yves M.


As an alternative to the selected answer...

The same could be achieved using the Serverless Framework, Webpack and the serverless-webpack plugin.

You can access options used for the serverless operation with:

const slsw = require('serverless-webpack');
const stage = slsw.lib.options.stage;

Or, you can access information in the serverless.yml file with:

const serverless = slsw.lib.serverless;

Then simply add this to the plugins of your webpack.config.js file:

plugins: [new EnvironmentPlugin({ VAR1: var1, VAR2: var2, STAGE: stage })]

This method can provide you with an easy way to manage environment variables in Lambda@Edge functions - read the case studies to see why the Serverless Framework is great.

like image 27
David Gettins Avatar answered Oct 04 '22 02:10

David Gettins