aws-sam-cli icon indicating copy to clipboard operation
aws-sam-cli copied to clipboard

Sam local Invoke lambda with local layer error

Open Cecarlego opened this issue 5 years ago • 12 comments

Description:

When invoking a function locally, which relies on a layer built locally as well, the function cannot find the module which is part of the layer. When uploading that layer through the AWS console, and changing the Layer's reference in the template.yaml file, the import works. The layer is 17Mb zipped, and contains the mysql-connector-python module, as well as the requests module.

Steps to reproduce the issue:

  1. Have a larger than 10MB layer (maybe more, just took the recommended max size from AWS console)
  2. Import layer's package and run sam local invoke FunctionName
  3. Deploy the layer manually in AWS console
  4. Run sam local invoke FunctionName again after changing the lambda's layers property to the remote ARN in template.yaml.

Observed result:

Failure when calling Layer locally:

Screenshot from 2019-05-17 11-20-40

Screenshot from 2019-05-17 11-20-55

Expected result:

Calling layer locally or from remote have the same output.

Cecarlego avatar May 17 '19 10:05 Cecarlego

The layer ... contains ... the requests module.

@Cecarlego - why wouldn't you simply import from botocore.vendored import requests as provided by aws? I know this doesn't directly solve the problem but just wanted to make sure you knew about this.

indyfin avatar Aug 23 '19 19:08 indyfin

@indyfin DO NOT do that. The vendored requests library is old and not updated, see https://github.com/boto/botocore/issues/1745#issuecomment-497833200 and https://github.com/boto/botocore/issues/1608

jfuss avatar Aug 26 '19 16:08 jfuss

I am also getting the same "unable to import package" error while invoking my lambda locally using 'sam local invoke FUNCTIONNAME'. Those packages are already present in layer(zipped folder). Is their any way to test these lamdas locally which are having python dependency zipped into layer.

Expectation is all the layer modules should get downloaded at some temp location while doing 'sam local invoke' so that it can take all the packages and run the lamda.

Capture

'apiconfig' module is already present in zipped layer.

surbhi029 avatar Oct 08 '19 17:10 surbhi029

Hey @surbhi029, there is a way to test the lambdas locally when using layers, but it requires the layer to be deployed in your AWS account, and changing the reference in your template.yaml file to be the layer's arn rather than the local file path to it.

Cecarlego avatar Oct 09 '19 08:10 Cecarlego

@Cecarlego We support layers that are local as well, just not ones that are already zipped. The value of Content or ContentUri (depending on the resource you are using for Layers), should be the directory to where the code is and be unzipped. If that is true, then we will pick up that layer, combine it with any other layers for the function and make it available in the container.

jfuss avatar Oct 09 '19 14:10 jfuss

Thanks a ton @Cecarlego @jfuss Both way it worked. I was stuck here from long back. Thanks again 👍

surbhi029 avatar Oct 09 '19 17:10 surbhi029

@Cecarlego We support layers that are local as well, just not ones that are already zipped. The value of Content or ContentUri (depending on the resource you are using for Layers), should be the directory to where the code is and be unzipped. If that is true, then we will pick up that layer, combine it with any other layers for the function and make it available in the container.

I have a dependencies folder that is unzipped, and be referred by ContentUri from template.yaml, however If install a custom module in dependencies by "file:my_modue_path", it's not working on Mac OS, but working on windows. Please check below: https://github.com/awslabs/aws-sam-cli/issues/1481

Thank you

XiamiYoung avatar Oct 28 '19 03:10 XiamiYoung

We don't follow paths in dependencies. Layer needs to be self contained, which is the same for the Lambda service.

jfuss avatar Oct 28 '19 13:10 jfuss

I just ran in to this issue. I was using a local zip file for the value of the ContentUri property within the LayerVersion. After switching this to a folder containing the contents of the zip file then a local invoke worked.

Is supporting zip files for a local invoke on the roadmap at all?

mikelax avatar Oct 29 '19 19:10 mikelax

Tracking as a feature request to handle this type of layer source. For now, what local supports is a reference to the layer source.

awood45 avatar Feb 03 '20 21:02 awood45

I encountered this same problem. I spun up the docker image and connected via a bash terminal. What I found was that the lambda zip file was indeed copied to the /opt directory, but that it was NOT unzipped. Hence the failure.

CJohnsonLehi avatar Feb 27 '20 20:02 CJohnsonLehi

I just ran in to this issue. I was using a local zip file for the value of the ContentUri property within the LayerVersion. After switching this to a folder containing the contents of the zip file then a local invoke worked.

The reason is as I mentioned above. The contents pointed to in ContentURI are simply copied over to the /opt directory, and not unzipped when using local invoke. I too can confirm that when I change the ContentUri value (In my template file): lambda-layers\python_files.zip to this: lambda-layers it indeed works.

CJohnsonLehi avatar Feb 27 '20 20:02 CJohnsonLehi

I do have the same issue, but layers dependencies are inside the requirements.txt. But not working, how can I do ?

lambait01 avatar Apr 22 '23 02:04 lambait01