aws / aws-sam-cli

CLI tool to build, test, debug, and deploy Serverless applications using AWS SAM
https://aws.amazon.com/serverless/sam/
Apache License 2.0
6.51k stars 1.17k forks source link

Bug: sam build with --manifest parametr and layer BuildMethod = makefile #5715

Open gorets opened 1 year ago

gorets commented 1 year ago

Description:

There are LambdaFunction & LambdaLayer in the my SAM template. LambdaLayer has BuildMethod: makefile

command sam build with parameter --manifest (-m) leads to error

**Build Failed Error: CustomMakeBuilder:MakeBuild - Make Failed: ~/sam-bug/package.json:1: * missing separator. Stop.

I think MakeBuild also has parameter -m and it use my value from input parameter --manifest

runs without --manifest is success

Steps to reproduce:

/template.yaml

AWSTemplateFormatVersion: "2010-09-09"
Transform: AWS::Serverless-2016-10-31
Description: Sam build bug

Resources:
  LambdaFunction:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: !Sub test-sam-build-${AWS::StackName}
      CodeUri: ./src
      Handler: lambda.handler
      Runtime: nodejs18.x
      Layers:
        - !Ref LambdaLayer

  LambdaLayer:
    Type: AWS::Serverless::LayerVersion
    Properties:
      ContentUri: ./layer/
      CompatibleRuntimes:
        - nodejs18.x
    Metadata:
      BuildMethod: makefile

/package.json

{
  "type": "module",
  "dependencies": {
    "@aws-lambda-powertools/logger": "^1.12.1"
  }
}

/layer/Makefile

build-LambdaLayer:
    mkdir -p "$(ARTIFACTS_DIR)/nodejs"
    cp package.json "$(ARTIFACTS_DIR)/nodejs"
    cp package-lock.json "$(ARTIFACTS_DIR)/nodejs"
    cd "$(ARTIFACTS_DIR)/nodejs" && npm install --production

Observed result:

2023-08-04 18:32:09,350 | Running workflow 'CustomMakeBuilder'                                                                                                                                            
2023-08-04 18:32:09,351 | Running CustomMakeBuilder:CopySource                                                                                                                                            
....
2023-08-04 18:32:09,361 | CustomMakeBuilder:CopySource succeeded                                                                                                                                          
2023-08-04 18:32:09,362 | Running CustomMakeBuilder:MakeBuild                                                                                                                                             
2023-08-04 18:32:09,363 | Current Artifacts Directory : /Users/test/Other/sam-bug/.aws-sam/build/LambdaLayer                                                                                            
2023-08-04 18:32:09,364 | **executing Make: ['make', '--makefile', '/Users/test/Other/sam-bug/package.json', 'build-LambdaLayer']**                                                                         
2023-08-04 18:32:09,384 | CustomMakeBuilder:MakeBuild failed           

Expected result:

Build success

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

  "version": "1.94.0",
  "system": {
    "python": "3.8.17",
    "os": "macOS-13.4.1-x86_64-i386-64bit"
  },
  "additional_dependencies": {
    "docker_engine": "24.0.2",
    "aws_cdk": "Not available",
    "terraform": "Not available"
  },
  "available_beta_feature_env_vars": [
    "SAM_CLI_BETA_FEATURES",
    "SAM_CLI_BETA_BUILD_PERFORMANCE",
    "SAM_CLI_BETA_TERRAFORM_SUPPORT",
    "SAM_CLI_BETA_RUST_CARGO_LAMBDA"
  ]
}
lucashuy commented 1 year ago

Hi, thanks for opening this issue. Just to confirm, the directory looks something like this:

├── layer
│   └── Makefile
├── package.json
├── src
│   └── lambda.js
└── template.yaml

Where there is a package.json at the root level, and you are executing sam build --manifest package.json?

If that is the case, would it be possible to move the package.json into the src and/or the layer folder, that way --manifest does not have to be provided? The issue appears to be coming from using --manifest for the Layer.

Since --manifest replaces the default file for the build method/runtime, it'll search for that file instead to use. When it builds the function, it expects a package.json so this is fine. However, --manifest will replace the file location for the layer's Makefile too.

gorets commented 1 year ago

Hi. I have a very complex project structure and the package.json file is located in a different directory, not near template.yaml. Therefore, when starting the build, I need to specify the custom path to the file package.json with --manifest parameter, but this breaks the layer build.

Due to this error, I can't use a custom folder structure in my project.

lucashuy commented 1 year ago

Would it be possible to adjust the folder structure to support using the package.json file without having to specify it? Is the package.json currently being reused for multiple resources? It might be possible to work around this if you are able to share the folder structure.

gorets commented 1 year ago

Hi. You can see my folder structure in example https://github.com/gorets/sam-bug

lucashuy commented 1 year ago

Thanks for taking the time to create a repository to show the file structure. Is there any particular reason sam build is being invoked as a script through npm? If the template was moved to the root, and the package.json is moved to src, then the template could be written in a way such that the package file is picked up by the Lambda functions and there wouldn't be a need to use the manifest option, if the package.json file is meant to be shared.

gorets commented 1 year ago

Yes, I can change the project structure and not use the --manifest option to define the path for package.json, but this does not solve the problem with the aws-cli library and others may have problems in the future.

Finndersen commented 1 month ago

I have also encountered this issue, and not specifying --manifest is not really an option. This is obviously a bug or incompatibility issue that should be resolved