Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sam build and sam local invoke differences regarding of LaverVersion in NodeJS #2222

Closed
kstro21 opened this issue Sep 15, 2020 · 4 comments
Closed
Labels

Comments

@kstro21
Copy link

kstro21 commented Sep 15, 2020

Description

ContentUri property of AWS::Serverless::LayerVersion behaves differently depending on the command used and it is annoying.
Currently, I have to use 2 different values, once to sam local invoke and another to run sam build.

Steps to reproduce

Here is the layer definition.

  CommonDependenciesLayer:
    Type: AWS::Serverless::LayerVersion
    Properties:
      LayerName: 'dev-common-dependencies-layer'
      Description: 'Common dependencies for dev env'
      ContentUri: './dependencies-layer'
      CompatibleRuntimes:
        - nodejs10.x
        - nodejs12.x
      RetentionPolicy: Retain
    Metadata:
      BuildMethod: nodejs10.x

Notice I'm using BuildMethod to build the layer when invoking sam build. The dependencies-layer folder looks like this

- dependencies-layer/
  |- node_modules
  |- package.json
  |- package-lock.json

I can invoke sam build then sam deploy and it works.

Now if I try to invoke a function that depends on the layer, it won't find any packages. We all know that the structure for a NodeJS layer is as follow:

- dependencies-layer/
  |- nodejs
    |- node_modules
    |- package.json
    |- package-lock.json

If I create the folder structure shown above, now sam local invoke works, but then sam build fails because the folder dependencies-layer does not contain a package.json.

There are a few ways we can handle this, like creating the folder nodejs copying the package.json in it then invoking npm install before sam local invoke. Or having both structures so both versions of the commands are happy but then we will have to maintain 2 versions of package.json. Or using a symlink, or using, etc.

Currently, I'm using a parameter, updated the value of ContentUri: !Ref MyParam and using sam local invoke --parameter-overrides MyParam=./dependencies-layer while the default value of the param is Default: './dependencies-layer/nodejs' but it feels like a hack.

Expected result

I would like that they both get to a mutual agreement so we don't have to do any extra step to make it work. I'm talking about sam build and sam local invoke

Additional environment details (Ex: Windows, Mac, Amazon Linux etc)

  1. OS: Amazon Linux
  2. sam --version: 1.2.0
@CoshUS CoshUS added area/local/invoke sam local invoke command area/deploy sam deploy command area/layers type/bug stage/needs-investigation Requires a deeper investigation labels Sep 15, 2020
@kstro21
Copy link
Author

kstro21 commented Dec 4, 2020

Any progress?

studds added a commit to studds/nx-aws that referenced this issue Feb 13, 2021
NB: the way that sam-cli handles layers is broken aws/aws-sam-cli#2222 - so... there's that
@lc-101
Copy link

lc-101 commented May 11, 2022

Any update on this?

@mndeveci
Copy link
Contributor

Hi all,

This should have been fixed since I can't re-produce this issue locally.

I have a function and layer in my template.yaml;

Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: hello-world/
      Handler: app.lambdaHandler
      Runtime: nodejs14.x
      Layers:
        - !Ref CommonDependenciesLayer

  CommonDependenciesLayer:
    Type: AWS::Serverless::LayerVersion
    Properties:
      LayerName: 'dev-common-dependencies-layer'
      Description: 'Common dependencies for dev env'
      ContentUri: './dependencies'
      CompatibleRuntimes:
        - nodejs14.x
        - nodejs16.x
      RetentionPolicy: Retain
    Metadata:
      BuildMethod: nodejs14.x

I am using axios as dependency, which is only defined in dependencies layer now;

const axios = require('axios')
const url = 'http://checkip.amazonaws.com/';
let response;

exports.lambdaHandler = async (event, context) => {
    try {
        const ret = await axios(url);
        response = {
            'statusCode': 200,
            'body': JSON.stringify({
                message: 'hello world',
                location: ret.data.trim()
            })
        }
    } catch (err) {
        console.log(err);
        return err;
    }

    return response
};

This is my source structure;

❯ tree .
.
├── dependencies
│   ├── node_modules
│   └── package.json
├── events
│   └── event.json
├── hello-world
│   └── app.js
└── template.yaml

4 directories, 4 files

And after I run sam build, this is my built folder structure (which adds nodejs folder for the layer);

 tree .aws-sam/build
.aws-sam/build
├── CommonDependenciesLayer
│   └── nodejs
│       ├── node_modules
│       │   ├── @ungap
│       │   ├── axios
│       │   │   ├── CHANGELOG.md
│       │   │   ├── LICENSE
│       │   │   ├── README.md
│       │   │   ├── SECURITY.md
│       │   │   ├── UPGRADE_GUIDE.md
│       │   │   ├── dist
│       │   │   │   ├── axios.js
│       │   │   │   ├── axios.map
│       │   │   │   ├── axios.min.js
│       │   │   │   └── axios.min.map
│       │   │   ├── index.d.ts
│       │   │   ├── index.js
│       │   │   ├── lib
│       │   │   │   ├── adapters
│       │   │   │   │   ├── README.md
│       │   │   │   │   ├── http.js
│       │   │   │   │   └── xhr.js
│       │   │   │   ├── axios.js
│       │   │   │   ├── cancel
│       │   │   │   │   ├── Cancel.js
│       │   │   │   │   ├── CancelToken.js
│       │   │   │   │   └── isCancel.js
│       │   │   │   ├── core
│       │   │   │   │   ├── Axios.js
│       │   │   │   │   ├── InterceptorManager.js
│       │   │   │   │   ├── README.md
│       │   │   │   │   ├── buildFullPath.js
│       │   │   │   │   ├── createError.js
│       │   │   │   │   ├── dispatchRequest.js
│       │   │   │   │   ├── enhanceError.js
│       │   │   │   │   ├── mergeConfig.js
│       │   │   │   │   ├── settle.js
│       │   │   │   │   └── transformData.js
│       │   │   │   ├── defaults.js
│       │   │   │   ├── helpers
│       │   │   │   │   ├── README.md
│       │   │   │   │   ├── bind.js
│       │   │   │   │   ├── buildURL.js
│       │   │   │   │   ├── combineURLs.js
│       │   │   │   │   ├── cookies.js
│       │   │   │   │   ├── deprecatedMethod.js
│       │   │   │   │   ├── isAbsoluteURL.js
│       │   │   │   │   ├── isAxiosError.js
│       │   │   │   │   ├── isURLSameOrigin.js
│       │   │   │   │   ├── normalizeHeaderName.js
│       │   │   │   │   ├── parseHeaders.js
│       │   │   │   │   ├── spread.js
│       │   │   │   │   └── validator.js
│       │   │   │   └── utils.js
│       │   │   └── package.json
│       │   └── follow-redirects
│       │       ├── LICENSE
│       │       ├── README.md
│       │       ├── debug.js
│       │       ├── http.js
│       │       ├── https.js
│       │       ├── index.js
│       │       └── package.json
│       └── package.json
├── HelloWorldFunction
│   └── app.js
└── template.yaml

13 directories, 54 files

And if I run sam local invoke it imports the library and executes successfully;

❯ sam local invoke
Invoking app.lambdaHandler (nodejs14.x)
CommonDependenciesLayer is a local Layer in the template
Building image........................
Skip pulling image and use local one: samcli/lambda:nodejs14.x-x86_64-e2462f05972210f55b560eea4.

Mounting /Volumes/workplace/other/gh-issues/cli-2222/sam-app/.aws-sam/build/HelloWorldFunction as /var/task:ro,delegated inside runtime container
START RequestId: 95850ee7-80ed-4097-9ff0-b12779b28978 Version: $LATEST
END RequestId: 95850ee7-80ed-4097-9ff0-b12779b28978
REPORT RequestId: 95850ee7-80ed-4097-9ff0-b12779b28978	Init Duration: 0.32 ms	Duration: 418.49 ms	Billed Duration: 419 ms	Memory Size: 128 MB	Max Memory Used: 128 MB
{"statusCode":200,"body":"{\"message\":\"hello world\",\"location\":\"x.x.x.x\"}"}%

I am going to resolve this issue for now, but please let us know if you are still experiencing this issue with an example for us to reproduce it.

Thanks!

@github-actions
Copy link
Contributor

⚠️COMMENT VISIBILITY WARNING⚠️

Comments on closed issues are hard for our team to see.
If you need more assistance, please either tag a team member or open a new issue that references this one.
If you wish to keep having a conversation with other community members under this issue feel free to do so.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants