为什么调试会在使用 "sam invoke local" 时中断对 AWS::Lamba::LayerVersion 的访问?
Why does debugging break access to an AWS::Lamba::LayerVersion when using "sam invoke local"?
这个有效:
sam local invoke -t template.local.yaml -e events/event-timezone.json GetTimezoneFunction
尝试使用 Visual Studio 代码进行调试时,这不起作用:
sam local invoke -t template.local.yaml -e events/event-timezone.json -d 5858 GetTimezoneFunction
不同之处在于,在第二个中,我收到一个错误消息,即未找到在我的 lambda 函数使用的单独层中定义的 npm 'axios' 模块。
Error: Cannot find module 'axios'
Require stack:
- /var/task/get-timezone.js
- /var/runtime/UserFunction.js
- /var/runtime/index.js
我能想到的是,也许通过尝试使用调试器,层的资源没有复制到 Docker 运行时环境,或者某些文件搜索路径被破坏。
我有另一个 lambda 函数,它不需要层中的任何东西,无论有没有调试器都可以正常工作。
带有getTimeZone
函数的文件开头为:
import axios from 'axios';
这是template.local.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: dependencies
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
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
这是我的 launch.json
:
{
"version": "0.2.0",
"configurations": [{
"name": "Debug get-timezone",
"type": "node",
"request": "attach",
"address": "localhost",
"port": 5858,
"localRoot": "${workspaceRoot}/dist",
"remoteRoot": "/var/task",
"protocol": "inspector",
"stopOnEntry": false,
"preLaunchTask": "local-tz-debug"
},
...
]
}
到目前为止,我在寻找这个问题的答案时只发现了很多未解决的问题和一些不完全相同的问题。
我让我的一个 lambda 函数转储了 process.env
中的所有环境变量,并发现启用调试(通过 -d 5858
)和未启用调试之间存在一些差异,大多数值得注意的是,启用调试时未定义 NODE_PATH
。
我想我曾经尝试修复 NODE_PATH
一次,基于我在其他地方读到的类似问题,但它似乎没有帮助。
现在我正在转储环境变量,但是,我可以看到我在 env.json
文件中定义 NODE_PATH
的尝试没有任何效果。那时我发现 SAM 忽略了任何未在我的模板中明确定义的环境变量,无论是作为全局变量还是针对每个 lambda。
这解决了那个问题:
Globals:
Function:
Timeout: 30
Environment:
Variables:
NODE_PATH: /opt/nodejs/node12/node_modules:/opt/nodejs/node_modules:/var/runtime/node_modules
一旦我解决了这个问题,然后它发现我需要调整我的 launch.json
以获得适用于 TypeScript 的调试器断点:
{
"version": "0.2.0",
"configurations": [{
"name": "Debug get-timezone",
"type": "node",
"request": "attach",
"address": "localhost",
"port": 5858,
"localRoot": "${workspaceRoot}/dist/get-timezone", // <- More specific path needed
"remoteRoot": "/var/task",
"protocol": "inspector",
"stopOnEntry": false,
"preLaunchTask": "local-tz-debug",
"outFiles": [ // <- Added this
"${workspaceRoot}/dist/get-timezone/**/*.js"
],
"sourceMaps": true // <- Added this
},
...
]
}
我只想为本地测试定义 NODE_PATH
变量,而不是为部署定义,所以我有一个单独的 template.yaml
文件,没有该定义用于部署。 template.yaml
还将 LayerVersion
的 Content
定义为 nodejs.zip
,而不是 dependencies
。我从 template.yaml
自动生成 template.local.yaml
,这样我就不必维护两个独立的几乎相同的模板。
我希望将来有更好的方法来做到这一点,但现在它已经完成了工作。
这个有效:
sam local invoke -t template.local.yaml -e events/event-timezone.json GetTimezoneFunction
尝试使用 Visual Studio 代码进行调试时,这不起作用:
sam local invoke -t template.local.yaml -e events/event-timezone.json -d 5858 GetTimezoneFunction
不同之处在于,在第二个中,我收到一个错误消息,即未找到在我的 lambda 函数使用的单独层中定义的 npm 'axios' 模块。
Error: Cannot find module 'axios'
Require stack:
- /var/task/get-timezone.js
- /var/runtime/UserFunction.js
- /var/runtime/index.js
我能想到的是,也许通过尝试使用调试器,层的资源没有复制到 Docker 运行时环境,或者某些文件搜索路径被破坏。
我有另一个 lambda 函数,它不需要层中的任何东西,无论有没有调试器都可以正常工作。
带有getTimeZone
函数的文件开头为:
import axios from 'axios';
这是template.local.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: dependencies
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
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
这是我的 launch.json
:
{
"version": "0.2.0",
"configurations": [{
"name": "Debug get-timezone",
"type": "node",
"request": "attach",
"address": "localhost",
"port": 5858,
"localRoot": "${workspaceRoot}/dist",
"remoteRoot": "/var/task",
"protocol": "inspector",
"stopOnEntry": false,
"preLaunchTask": "local-tz-debug"
},
...
]
}
到目前为止,我在寻找这个问题的答案时只发现了很多未解决的问题和一些不完全相同的问题。
我让我的一个 lambda 函数转储了 process.env
中的所有环境变量,并发现启用调试(通过 -d 5858
)和未启用调试之间存在一些差异,大多数值得注意的是,启用调试时未定义 NODE_PATH
。
我想我曾经尝试修复 NODE_PATH
一次,基于我在其他地方读到的类似问题,但它似乎没有帮助。
现在我正在转储环境变量,但是,我可以看到我在 env.json
文件中定义 NODE_PATH
的尝试没有任何效果。那时我发现 SAM 忽略了任何未在我的模板中明确定义的环境变量,无论是作为全局变量还是针对每个 lambda。
这解决了那个问题:
Globals:
Function:
Timeout: 30
Environment:
Variables:
NODE_PATH: /opt/nodejs/node12/node_modules:/opt/nodejs/node_modules:/var/runtime/node_modules
一旦我解决了这个问题,然后它发现我需要调整我的 launch.json
以获得适用于 TypeScript 的调试器断点:
{
"version": "0.2.0",
"configurations": [{
"name": "Debug get-timezone",
"type": "node",
"request": "attach",
"address": "localhost",
"port": 5858,
"localRoot": "${workspaceRoot}/dist/get-timezone", // <- More specific path needed
"remoteRoot": "/var/task",
"protocol": "inspector",
"stopOnEntry": false,
"preLaunchTask": "local-tz-debug",
"outFiles": [ // <- Added this
"${workspaceRoot}/dist/get-timezone/**/*.js"
],
"sourceMaps": true // <- Added this
},
...
]
}
我只想为本地测试定义 NODE_PATH
变量,而不是为部署定义,所以我有一个单独的 template.yaml
文件,没有该定义用于部署。 template.yaml
还将 LayerVersion
的 Content
定义为 nodejs.zip
,而不是 dependencies
。我从 template.yaml
自动生成 template.local.yaml
,这样我就不必维护两个独立的几乎相同的模板。
我希望将来有更好的方法来做到这一点,但现在它已经完成了工作。