无法从 AWS Lambda 层导入“yaml”模块

Jus*_*tin 5 python aws-lambda

我有一个非常简单的 Python3.6 Lambda 函数,唯一的复杂性是我想包含pyyaml在其中。index.py看起来像这样 -

import yaml

def handler(event, context):
    return event
Run Code Online (Sandbox Code Playgroud)

如果我捆绑pyyaml在我的 Lambda 可部署中,一切都会正常工作,如下所示 -

(aws_layer_demo) justin@justin-XPS-13-9360:~/work/aws_demos/aws_layer_demo$ jar -tvf  tmp/layer-demo-dev/2019-05-31-06-27-41.zip 
    59 Fri May 31 06:27:13 BST 2019 index.py
     0 Fri May 31 06:19:32 BST 2019 __init__.py
  4881 Fri May 31 06:15:37 BST 2019 yaml/composer.py
 25554 Fri May 31 06:15:37 BST 2019 yaml/constructor.py
  3294 Fri May 31 06:15:37 BST 2019 yaml/cyaml.py
                                    {... etc ...}
Run Code Online (Sandbox Code Playgroud)

我可以 ping Lambda 函数并获得响应,没问题。

现在我想测试包括pyyaml在一个层内。所以我现在有两个可部署的东西,一个用于应用程序 -

(aws_layer_demo) justin@justin-XPS-13-9360:~/work/aws_demos/aws_layer_demo$ jar -tvf  tmp/layer-demo-dev/2019-05-31-06-43-42.zip 
    59 Fri May 31 06:27:13 BST 2019 index.py
     0 Fri May 31 06:19:32 BST 2019 __init__.py
Run Code Online (Sandbox Code Playgroud)

和一层 -

(aws_layer_demo) justin@justin-XPS-13-9360:~/work/aws_demos/aws_layer_demo$ jar -tvf tmp/layer-demo-layer-dev/2019-05-31-06-43-42.zip 
     0 Fri May 31 06:43:42 BST 2019 __init__.py
  4881 Fri May 31 06:15:37 BST 2019 yaml/composer.py
 25554 Fri May 31 06:15:37 BST 2019 yaml/constructor.py
  3294 Fri May 31 06:15:37 BST 2019 yaml/cyaml.py
                                    {... etc ...}
Run Code Online (Sandbox Code Playgroud)

我已经使用 Cloudformation 堆栈(通过 S3)部署了两者,看起来函数和层都已正确部署 -

(aws_layer_demo) justin@justin-XPS-13-9360:~/work/aws_demos/aws_layer_demo$ ./scripts/show_function_config.sh dev
------------------------------------------------------------------------------------------------
|                                   GetFunctionConfiguration                                   |
+--------------+-------------------------------------------------------------------------------+
|  CodeSha256  |  MImn7X/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX=                                 |
|  CodeSize    |  372                                                                          |
|  Description |                                                                               |
|  FunctionArn |  arn:aws:lambda:eu-west-1:XXXXXXXXXXXX:function:layer-demo-dev                |
|  FunctionName|  layer-demo-dev                                                               |
|  Handler     |  index.handler                                                                |
|  LastModified|  2019-05-31T05:44:14.089+0000                                                 |
|  MemorySize  |  512                                                                          |
|  RevisionId  |  XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX                                         |
|  Role        |  arn:aws:iam::XXXXXXXXXXXX:role/layer-demo-dev-AppFunctionRole-XXXXXXXXXXXX   |
|  Runtime     |  python3.6                                                                    |
|  Timeout     |  5                                                                            |
|  Version     |  $LATEST                                                                      |
+--------------+-------------------------------------------------------------------------------+
||                                           Layers                                           ||
|+-------------+------------------------------------------------------------------------------+|
||  Arn        |  arn:aws:lambda:eu-west-1:XXXXXXXXXXXX:layer:layer-demo-dev:2                ||
||  CodeSize   |  41184                                                                       ||
|+-------------+------------------------------------------------------------------------------+|
||                                        TracingConfig                                       ||
|+-------------------------------+------------------------------------------------------------+|
||  Mode                         |  PassThrough                                               ||
|+-------------------------------+------------------------------------------------------------+|
||                                          VpcConfig                                         ||
|+---------------------------------------------------------------+----------------------------+|
||  VpcId                                                        |                            ||
|+---------------------------------------------------------------+----------------------------+|

Run Code Online (Sandbox Code Playgroud)

特别注意上面的“层”,以及 CodeSize > 0 的事实(即我没有意外部署大小为零的 zip 文件)

但是当我 ping 新分层的 Lambda 函数时,我现在得到 -

Unable to import module 'index'
Run Code Online (Sandbox Code Playgroud)

如果我更深入地研究 Cloudwatch 日志,我会得到 -

Unable to import module 'index': No module named 'yaml'
Run Code Online (Sandbox Code Playgroud)

所以。感觉好像我可能以某种方式错误地构造了我的层包(就目录结构而言),以便 Lambdayaml在内部 AWS上看不到PYTHONPATH。或者其他的东西。谁能告诉我哪里可能出错?

非常感谢。

Jus*_*tin 3

事实证明,这是由于几个因素造成的。

首先,您必须非常小心地构建层包结构。仅压缩依赖项是不够的 - 对于 Python Lambda 函数,它们必须安装在pythonzip 文件内的目录中。该目录会根据您使用的运行时而变化。Lambda 文档中不是特别清楚,但这里有更多详细信息 -

https://medium.com/@adhorn/getting-started-with-aws-lambda-layers-for-python-6e10b1f9a5d

其次,在部署该层时,您需要指定兼容的运行时 - 因此,如果您使用 AWS CLI,则类似于 -

aws lambda publish-layer-version --layer-name $appname --content S3Bucket=$s3bucketname,S3Key=$appname/layer.zip --compatible-runtimes python3.7
Run Code Online (Sandbox Code Playgroud)

按照这两个步骤操作,您的图层应该可以正常工作。