amazon-web-servicesenvironment-variablesaws-lambda-edge

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).


Solution

  • 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