erki
erki

Reputation: 25

AWS Lambda function with ImageMagick layer on Nodejs10.x

I have been trying to create a Lambda function that uses the ImageMagick CLI to convert high resolution images to offload my server. I have deployed the imagemagick-aws-lambda-2 and extracted the layer and added it to my function, but I have not been successful in calling the imagemagick CLI. Everything I try just gets a "Error: Command failed: convert: No such file or directory".

I have tried other layers, I have tried downloading the layers and adding them manually to the function, I have tried setting the PATH variables in different ways, but still haven't been able to get it to work. When deploying it to Lambda I can see my layer has been embedded properly in my function. At this point I would just like to get the most basic use case to work with the "convert" command.

My template.yaml:

Transform: AWS::Serverless-2016-10-31
Description: >
  wpPoster

  Sample SAM Template for wpPoster

Globals:
  Function:
    Timeout: 60

Resources:
  TestPosterFunction:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: TestPoster
      Description: Test of TestPoster function
      CodeUri: test-poster/
      Handler: index.lambdaHandler
      Runtime: nodejs10.x
      Layers:
        - arn:aws:lambda:eu-west-1:xxxxxxxxxxxxx:layer:image-magick:1

My index.js:

const exec = require('child_process').exec;

exports.lambdaHandler = function(event, context, callback) {
    exec('convert -version', function(error, stdout, stderr) {
        if (error) {
            console.log(error);
        }
        console.log(stdout);
    });

    callback();
};

I'm using VS Studio Code with AWS SAM for coding and testing locally, which should download and cache any external layer.

Upvotes: 1

Views: 2258

Answers (1)

Phil
Phil

Reputation: 53

Strange, seems like something is wrong with the environment paths or the layer packages.

A layer is copied into "/opt". In the docs it is specified that one needs to put a binary into folder "bin" and create a "zip" archive. So the path to the binary at the time of execution is, for example, "/opt/bin/convert". "/opt/bin" should be in the Node environment path.

I would suggest:

  1. Try specifying an absolute path "/opt/bin/convert -version"
  2. If still "No such file or directory", then download the layer, unarchive it on your machine and check what is the folder structure

P.S. I copied your "template.yaml" (replaced Resources.TestPosterFunction.Properties.Layers with an arn of a random layer in my AWS account) and "index.js" (called my executable instead, "executable -version") and everything works perfectly ("sam local invoke TestPosterFunction"). My example layer consists of exactly this:

📦bin
 ┣ 📜executable

Upvotes: 1

Related Questions