Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AWS: Layer code not found when using "sam invoke local"

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.

like image 725
kshetline Avatar asked Dec 13 '19 15:12

kshetline


1 Answers

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.

like image 56
Shamshiel Avatar answered Oct 03 '22 03:10

Shamshiel