I'm working on a sample AWS project that creates two lambda functions. These functions share common code from node_modules
which has been placed in a separate layer (specifically AWS::Lambda::LayerVersion
, not AWS::Serverless::LayerVersion
). I can deploy this code and it works correctly when I test the deployed version.
However, when I try to test the code locally using sam invoke local
, the common code is not found. I get this error (I'm trying to use the npm package "axios"):
{"errorType":"Runtime.ImportModuleError","errorMessage":"Error: Cannot find module 'axios'\nRequire stack:\n- /var/task/get-timezone.js\n- /var/runtime/UserFunction.js\n- /var/runtime/index.js"}
This is my template.yaml
:
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: AWS Sample
Globals:
Function:
Timeout: 30
Resources:
SampleCommonLayer:
Type: AWS::Lambda::LayerVersion
Properties:
CompatibleRuntimes:
- nodejs12.x
Content: nodejs.zip
Description: Sample Common LayerVersion
LayerName: SampleCommonLayer
GetTimezoneFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: dist/get-timezone
Handler: get-timezone.getTimezone
Runtime: nodejs12.x
Layers:
- !Ref SampleCommonLayer
Events:
GetTimezone:
Type: Api
Properties:
Path: /get-timezone
Method: get
ReverseFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: dist/reverse
Handler: reverse.reverse
Runtime: nodejs12.x
Layers:
- !Ref SampleCommonLayer
Events:
Reverse:
Type: Api
Properties:
Path: /reverse
Method: get
Outputs:
GetTimezoneApi:
Description: "API Gateway endpoint URL for Prod stage for getTimezone function"
Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/get-timezone/"
GetTimezoneFunction:
Description: "getTimezone Lambda Function ARN"
Value: !GetAtt GetTimezoneFunction.Arn
GetTimezoneFunctionIamRole:
Description: "Implicit IAM Role created for getTimezone function"
Value: !GetAtt GetTimezoneFunctionRole.Arn
ReverseApi:
Description: "API Gateway endpoint URL for Prod stage for reverse function"
Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/reverse/"
ReverseFunction:
Description: "reverse Lambda Function ARN"
Value: !GetAtt ReverseFunction.Arn
ReverseFunctionIamRole:
Description: "Implicit IAM Role created for reverse function"
Value: !GetAtt ReverseFunctionRole.Arn
I'm invoking the GetTimezone function like this:
sam local invoke --layer-cache-basedir layer-cache --force-image-build \"GetTimezoneFunction\" --event events/event-timezone.json -d 5858
Nothing ever gets copied into the layer-cache
directory, and I'm sure that's part of the problem, but I can't figure out how I'd fix that.
I've searched for answers to this problem, but so far I've only found unanswered questions, or answers that don't match my particular situation.
Most of the somewhat-related questions involve AWS::Serverless::LayerVersion
, not AWS::Lambda::LayerVersion
. I've tried using Serverless
instead, but that hasn't helped.
UPDATE:
If I change...
Layers:
- !Ref SampleCommonLayer
...to...
Layers:
- arn:aws:lambda:us-east-2:xxxxxxxxxxxx:layer:SampleCommonLayer:y
...using an already-deployed layer (where xxxxxxxxxxxx
and y
are a specific ID and version) then sam local invoke
works. But I don't want to use something I have to deploy first, I want to use the latest local not-yet-deployed code.
This is known issue: https://github.com/awslabs/aws-sam-cli/issues/947
Currently the "workaround" is to use the directory of the layer instead of a zip file.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With