使用 AWS SAM 为 Python 创建 AWS Lambda 层(无服务器应用程序模型)

使用 AWS SAM 为 Python 创建 AWS Lambda 层(无服务器应用程序模型)

我正在尝试使用 AWS SAM/无服务器应用程序模型将 Python 和本机库的组合部署到 Lambda 作为层,以供 Python Lambda 函数使用。如果您能帮助我完成构建和部署,我将不胜感激。

我最初的 POC 是手动创建一个测试 lambda 函数并将本机 Oracle Instant Client 库打包在同一个 lambda zip 中。这很有效,所以现在我使用基础设施即代码将其部署为一个层,以便多个函数可以在该层中重用客户端。

这是我的 SAM 模板

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31

Globals:
  Function:
    Runtime: python3.8

Resources:
  OracleInstantClientLayer:
    Type: AWS::Serverless::LayerVersion
    Properties:
      ContentUri: LayerResources
      CompatibleRuntimes:
        - python3.8
    Metadata:
      #BuildMethod: makefile
      BuildMethod: python3.8

在“LayerResources”子目录中我有

  • Makefile
  • requirements.txt(其中只有一行,包含 cx_Oracle)
  • abc.so(为 x86 Linux 编译的一组库文件)

当我的模板指定“BuildMethod python3.8”时,Python 库会按预期下载并放入“.aws.sam\build\OracleInstantClientLayer\python”文件夹中,但本机库 abc.so 却没有。我尝试过“sam build”和“sam build --use-container”,结果相同。

我也尝试过用这个 makefile 执行“BuildMethod makefile”。我试图将所有文件放入“BuildTest”文件夹中,这可能不太正确,但这将是向前迈出的一步。

build-OracleInstantClientLayer:
    python -m pip install -r requirements.txt -t "BuildTest"
    cp LayerResources\* BuildTest\

当我“sam build”时出现错误

sam build
Building layer 'OracleInstantClientLayer'
Running CustomMakeBuilder:CopySource
Running CustomMakeBuilder:MakeBuild
Current Artifacts Directory : C:\ProjectFolder\.aws-sam\build\OracleInstantClientLayer
python -m pip install -r requirements.txt -t "BuildTest"
Collecting cx_Oracle
  Using cached cx_Oracle-8.3.0-cp38-cp38-win_amd64.whl (219 kB)
Installing collected packages: cx_Oracle
Successfully installed cx_Oracle-8.3.0
cp LayerResources\* BuildTest\

Build Failed
Error: CustomMakeBuilder:MakeBuild - Make Failed: process_begin: CreateProcess(NULL, cp LayerResources* BuildTest, ...) failed.
make (e=2): The system cannot find the file specified.
make: *** [C:\ProjectFolder\LayerResources\Makefile:3: build-OracleInstantClientLayer] Error 2

有人能帮忙吗?我更喜欢使用 AWS SAM,但我也愿意手动创建层 zip 文件并使用 SAM 上传,这是我尚未尝试过的后备方法。

答案1

我的结论是 AWS SAM 不是为了创建层 zip 文件而制作的。这是我使用的命令。层文件放在 LayerBuild 文件夹中。对于 Python,需要放在 LayerBuild\python 中,因为当它上传到 lambda 服务器时,它会被解压到 opt (文档在这里)。

7za a -tzip LayerBuild\LambdaLayer.zip .\LayerBuild\*

aws s3 cp --profile %1 LayerBuild\LambdaLayer.zip s3://bucketname/foldername/LambdaLayer.zip

aws lambda publish-layer-version --profile AwsProfileName --layer-name LayerName --description "xyz" --compatible-runtimes python3.9 --content S3Bucket=bucketname,S3Key=lambda/LambdaLayer.zip

创建 lambda 函数时,请务必设置 LD 库路径

Function:
    Type: AWS::Serverless::Function
    Properties:
      Description: Lambda function
      FunctionName: Function
      CodeUri: python-code/
      Role: RoleName
      Handler: LambdaFileName.lambda_handler
      VpcConfig:
        SecurityGroupIds:
          - SG-ID
        SubnetIds:
         - Subnet1-ID
         - Subnet1-ID
      Environment:
        Variables:
          LD_LIBRARY_PATH: '/var/lang/lib:/lib64:/usr/lib64:/var/runtime:/var/runtime/lib:/var/task:/var/task/lib:/opt/lib:/opt/python'
      Layers:
       - Layer URI

相关内容