【问题标题】:SAM build - does it also build layers?SAM 构建 - 它还构建层吗?
【发布时间】:2020-02-12 14:11:34
【问题描述】:

我对 lambda 和 SAM 都是新手 - 所以如果我搞砸了任何简单的事情,请不要大喊:D。

总结:我无法让sam build构建template.yaml中指定的层,它只构建了lambda函数。

背景:我正在尝试在 python3.7 中构建一个使用 skimage (scikit-image) 模块的 lambda 函数。为此,我正在尝试使用 SAM 来构建和部署它。 ...这是有效的

我正在尝试将 scikit-image 模块部署为一个层(并且还使用 SAM 构建),而不是将其包含在 lambda 函数方向中...这不起作用


首先,我只是扩展标准 SAM Hello World 应用程序。

我只需将 skimage 添加到 requirements.txt ,然后使用 sam build -u,然后从构建的包目录中手动删除 numpy/scipy 依赖项(我已经包含 AWS scipy/numpy 层)就可以工作了.

(我将 import numpy、scipy.ndimage 和 skimage.draw 添加到标准的 hello world 应用程序中,并为每个应用程序添加了一些测试函数调用)

requirements.txt:

requests
scikit-image

之后,一切正常(在本地和/或 AWS 上运行)。


但是,我现在想将 skimage 模块从我的应用程序中移出并移到一个新的自定义层中(我想将 skimage 放在一个层中以重复用于一些功能)

为了设置它,我创建了一个依赖项目录并将 requirements.txt 移到那里(在 app 目录中留下空的 requirements.txt)。 然后我更新了 template.yaml 以指定新层:

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
  sam-app

  Sample SAM Template for sam-app

# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
  Function:
    Timeout: 3

Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: hello_world/
      Handler: app.lambda_handler
      Runtime: python3.7
      Layers:
              - arn:aws:lambda:us-west-2:420165488524:layer:AWSLambda-Python37-SciPy1x:2
              - !Ref SkimageLayer
      Events:
        HelloWorld:
          Type: Api
          Properties:
            Path: /hello
            Method: get

  SkimageLayer:
    Type: AWS::Serverless::LayerVersion
    Properties:
      LayerName: Skimage
      Description: Skimage module layer
      ContentUri: dependencies/
      CompatibleRuntimes:
              - python3.7
      RetentionPolicy: Retain
    DependsOn:
            - Skimage

目录结构:

▾ dependencies/                
    requirements.txt (responses and scikit-image)          
▸ events/                      
▾ hello_world/                 
    __init__.py                
    app.py                     
    requirements.txt (now empty)          
▸ tests/                       
  README.md                    
  template.yaml                 

但是,当我使用该模板文件运行 sam build -u 时,没有为 template.yml 文件中 ./dependencies: SkimageLayer 中指定的层构建任何内容。但是HelloWorldFunction 仍然可以正确构建(当然现在没有任何包含的模块)

【问题讨论】:

  • 我正在基于此工作一点:noise.getoto.net/2019/02/06/…。大约一半时,他暗示 SAM build 不会自己构建层,因为他在节点依赖项目录中手动运行 npm install 来安装节点依赖项

标签: aws-lambda aws-lambda-layers


【解决方案1】:

由于SAM Cli version v0.50.0,它正在构建层作为sam build 的一部分。

Design document 可能是了解其工作原理的良好起点。

基本上,您必须使用 lambda 的目标运行时设置自定义 BuildMethod

MyLayer:
Type: AWS::Serverless::LayerVersion
Properties:
  ContentUri: my_layer
  CompatibleRuntimes:
    - python3.8
Metadata:
  BuildMethod: python3.8 (or nodejs8.10 etc..)

警告:对于 Java 这样的编译语言,它has a issue 会尝试在函数之前构建层。预计会在下一个版本中修复 (PR opened already)。

【讨论】:

    【解决方案2】:

    快速答案 - no ,目前sam做 not build em>图层你定义了sam template.yaml file。

    它将构建您定义的任何函数

    但是(奇怪)它包(上传到s3)并部署(在aws内设置,分配ARN,可以使用它等)您定义的任何图层。

    SAM Github问题上有一个功能请求,以实现带SAM的图层建筑物。


    t 他实际上可以自动被黑客攻击以获得SAM以通过在SAM模板文件中创建虚拟函数以及图层中的虚拟函数来构建您的图层和。为函数创建的 .aws-sam 构建目录的 ContentUri 入口点。

    See my post here on that.

    这种方法实际上似乎在现在扭曲山姆时似乎很好地为你建造你的层。

    【讨论】:

      【解决方案3】:

      我不确定最近是否发生了变化,但我可以毫无问题地做到这一点。我的模板文件和结构与 OP 非常相似,只是我已将所有常用代码放入...

      /dependencies/python/lib/python3.7/site-packages/

      我没有在该目录中包含 requirements.txt 文件...只是 __init__.py 文件和我需要导入到我的函数中的各种 .py 文件。

      SAM 然后找到代码并构建层。你甚至不需要像一些教程告诉你的那样压缩目录的内容。

      最好的部分是Layers: 可以放入模板文件的Globals: 部分,以便该层可用于您的所有功能!

      Globals:
        Function:
          Handler: main.lambda_handler
          Timeout: 10
          Runtime: python3.7
          Layers: 
              - !Ref HelperFunctions
      
      Resources:
        HelperFunctions:
          Type: AWS::Serverless::LayerVersion
          Properties:
            LayerName: MyHelperFunctions
            Description: My Lambda Layer with Helper Functions for accessing RDS, Logging, and other utilities.
            ContentUri: dependencies/
            CompatibleRuntimes:
              - python3.6
              - python3.7
            LicenseInfo: MIT
            RetentionPolicy: Delete
      

      【讨论】:

      • 欣赏这个答案 - 我会尝试这种方法。
      • 现在的问题是您在本地构建所有依赖项。有些可能在部署后无法工作。例如numpy 会有这个问题。
      • 路径很重要。 'dependencies' 的目录名称只是我选择的一个,但它下面的所有内容都很重要,必须遵循此配置。如果这样做,则应在上传图层时找到站点包。我没有尝试用 numpy 来做,但我不明白它是如何工作的。
      • @Karuhanga - 当您使用 SAM 时,可以选择使用 sam build(我认为是 -u 标志?)在 AWS lambda 环境 docker 容器中构建。这样它在本地构建,但使用正确的 AWS 环境。因此,一切都是为 lambda 构建的。我将它用于 numpy 等没有问题。
      • @Karuhanga - 另请注意 - AWS 提供了一个预构建的 numpy/scipy 层供您使用 - 如果您只需要一个层,您不需要为 numpy/scipy 构建自己的层为。
      【解决方案4】:

      相对于这些较早的答案,AWS 团队一定让事情变得更容易了。在当前文档中,您所做的只是在模板中将图层列为属性(2020 年 11 月):

      ServerlessFunction:
        Type: AWS::Serverless::Function
        Properties:
          CodeUri: .
          Handler: my_handler
          Runtime: Python3.7
          Layers:
              - arn:aws:lambda:us-west-2:111111111111:layer:myLayer:1
              - arn:aws:lambda:us-west-2:111111111111:layer:mySecondLayer:1
      

      https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-layers.html

      【讨论】:

      • OP 问题是关于使用 SAM 模板构建层而不是在 SAM 模板中重用层
      • 好点@VadimK。希望有人仍然会从我的评论中找到用处,因为它是相关的,而且没有太多。
      【解决方案5】:

      我让它与以下脚本一起工作。使用 Ubuntu 18 和 CodeBuild 测试

      它 pip install 将层的要求设置为.aws-sam/build/layername/python/。然后你可以正常运行sam packagesam deploy

      build-layers.py:

      import yaml
      import subprocess
      import sys
      import shutil
      
      SAM_BUILD_PATH = ".aws-sam/build"
      
      with open("template.yaml", "r") as f:
          template = yaml.safe_load(f)
      
      for key, resource in template["Resources"].items():
          if resource["Type"] not in ["AWS::Serverless::LayerVersion", "AWS::Lambda::LayerVersion"]:
              continue
          properties = resource["Properties"]
          content_uri = properties["ContentUri"]
          layer_name = properties["LayerName"]
          requirements_path = f"{content_uri}/requirements.txt"
      
          subprocess.check_call([sys.executable, "-m", "pip", "install", "-r", requirements_path, "-t", f"{SAM_BUILD_PATH}/{layer_name}/python"])
      
      shutil.copyfile("template.yaml", f"{SAM_BUILD_PATH}/template.yaml")
      

      template.yaml:

      Transform: AWS::Serverless-2016-10-31
      
      Resources:
        pandas:
          Type: AWS::Serverless::LayerVersion
          Properties:
            LayerName: pandas
            ContentUri: pandas
            CompatibleRuntimes:
              - python3.6
              - python3.7
              - python3.8
        sqlparse:
          Type: AWS::Serverless::LayerVersion
          Properties:
            LayerName: sqlparse
            ContentUri: sqlparse
            CompatibleRuntimes:
              - python3.6
              - python3.7
              - python3.8
      

      所以先拨打python build-layers.py,然后拨打sam package,然后拨打sam deploy

      我的目录如下所示:

      lambda
        layers
          pandas
            requirements.txt (content = pandas)
          sqlparse
            requirements.txt (content = sqlparse)
        template.yaml
        build-layers.py
      

      buildspec.yml:

      ---  # build spec for AWS CodeBuild
      
      version: 0.2
      
      phases:
        install:
          runtime-versions:
            python: 3.8
          commands:
            - pip install aws-sam-cli
        build:
          commands:
            - cd lambda/layers
            - python build-layers.py
            - sam package --s3-bucket foo --s3-prefix sam/lambda/layers | sam deploy --capabilities CAPABILITY_IAM -t /dev/stdin --stack-name LAYERS
      

      【讨论】:

      • 嘿,尼尔 - 我得检查一下。 ...您可以在 指定函数的情况下使用它吗?以前“欺骗”SAM 为您构建层的唯一方法是将其与虚拟函数相关联。您不能在模板 yaml 文件中仅指定一个层。但你似乎能够做到这一点!如果他们现在改变了,那就太好了
      • 甜蜜——那我得去看看
      猜你喜欢
      • 2020-10-28
      • 2011-05-13
      • 2016-12-28
      • 2022-06-16
      • 1970-01-01
      • 2022-06-10
      • 1970-01-01
      • 2020-05-07
      • 2020-10-23
      相关资源
      最近更新 更多