sam build and sam local invoke differences regarding of LaverVersion in NodeJS
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)
- OS: Amazon Linux
-
sam --version: 1.2.0
Any progress?
Any update on this?
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!
⚠️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.