简体   繁体   English

具有相同 CodeUri 的 AWS 多个 lambda

[英]AWS multiple lambdas with same CodeUri

I have multiple lambdas in my AWS serverless project and they all have the same CodeUri which is a folder in my project.我的 AWS 无服务器项目中有多个 lambda,它们都有相同的CodeUri ,它是我项目中的一个文件夹。 For example, they all point to src/ .例如,它们都指向src/

In the basic usage, or at least how I use it, the sam build option create a folder for each lambda.在基本用法或至少我如何使用它时, sam build选项为每个 lambda 创建一个文件夹。 All of the folders contain the same code.所有文件夹都包含相同的代码。 Then, when running sam deploy each zip is uploaded to S3.然后,在运行sam deploy时,每个 zip 都会上传到 S3。 The zips are all the same and it takes a lot of redundent time to upload them all.拉链都是一样的,上传它们需要大量的冗余时间。

Is there an option "to tell" sam to upload it only once?是否有“告诉”山姆只上传一次的选项?

I saw that I can build the zip manually, then uploading it to S3.我看到我可以手动构建 zip,然后将其上传到 S3。 How can I then set the uri in the CodeUri of the lambdas?然后如何在 lambda 的CodeUri中设置 uri? Should I do it using external parameter or there is dedicated way to signal it?我应该使用外部参数还是有专门的方式来发出信号?

Thank you谢谢

After hard effort, using David Conde's idea, I managed to find some solution for it.经过艰苦的努力,使用大卫康德的想法,我设法找到了一些解决方案。 What we want to achieve is uploading the lambda's zip (with all of it's dependencies) once and point all the lambdas to use this zip.我们想要实现的是一次上传 lambda 的 zip(及其所有依赖项)并指向所有 lambda 以使用此 zip。

This process is seperated into couple of steps which I'll try to describe in much details as I can.这个过程分为几个步骤,我将尽可能详细地描述这些步骤。 Some of them might not be relevant exactly for your case.其中一些可能与您的情况不完全相关。

General idea大概的概念

The general idea is to create a layer which contains the code we want to upload once.一般的想法是创建一个包含我们要上传一次的代码的层。 Then, for each lambda, specify it uses this layer.然后,对于每个 lambda,指定它使用该层。 Each lambda will have it handler points to somewhere in the source directory.每个 lambda 都会让它的处理程序指向源目录中的某个位置。 Hence, running code "from the layer".因此,“从层”运行代码。 But.但。 we must specify code for the lambda to run/attach a zip - even if it's not what going to run, To skip that.我们必须为 lambda 指定代码以运行/附加 zip - 即使它不会运行,也可以跳过它。 we are going to attach it an "empty" code.我们将为其附加一个“空”代码。

Build folder构建文件夹

First, create a build folder where we are going to work, for example: mkdir -p.build/首先,创建一个我们将要工作的构建文件夹,例如: mkdir -p.build/

In addition, define the following variables:此外,定义以下变量:

  • s3_bucket="aaaaaaaa"
  • s3_prefix="aaaaaaaa"
  • s3_lambda_zip_suffix="$s3_prefix/lambda.zip"
  • s3_lambda_zip="s3://$s3_bucket/$s3_lambda_zip_suffix"

Creating the source zip创建源 zip

When lambda is unzipped, it's content is written to the working directory. lambda 解压后,其内容被写入工作目录。 When a layer is unzipped, it is unzipped into /opt as documented in AWS.解压缩层时,会按照 AWS 中的说明将其解压缩到/opt中。 Because our lambda needs to find our source code, which is "a depndencie" it needs to find it under /opt .因为我们的 lambda 需要找到我们的源代码,这是一个“依赖项”,它需要在/opt下找到它。 To achieve it, we need it to be unzipped into /opt/python .为了实现它,我们需要将它解压缩到/opt/python中。 We can do that by zipping python/... into a zip file.我们可以通过将python/...压缩到 zip 文件中来做到这一点。

First, we create the folder we will install the dependencies into the python folder:首先,我们创建文件夹,将依赖项安装到 python 文件夹中:

  • mkdir -p.build/lambda_zip/python
  • pip3 install -q --target.build/lambda_zip/python -r requirements.txt

Then we zip it:然后我们zip吧:

  • pushd.build/lambda_zip/ > /dev/null
  • zip --quiet -r./lambda.zip./python
  • popd > /dev/null

Now, you probably want to add your src direcory:现在,您可能想要添加您的 src 目录:

  • zip --quiet -r.build/lambda_zip/lambda.zip src

#Uploading to S3 Now, we have to upload the zip into S3 for our lambdas to load it. #上传到 S3 现在,我们必须将 zip 上传到 S3 以便我们的 lambda 加载它。

  • aws s3 cp ".build/lambda_zip/lambda.zip" $s3_lambda_zip_path

Adding layer to template.yaml将层添加到template.yaml

Now, we need to add the layer into our template.yaml file, you can copy the following code after you read at AWS documentation:现在,我们需要将该层添加到我们的template.yaml文件中,您可以在阅读 AWS 文档后复制以下代码:

Parameters:
  LambdaCodeUriBucket:
    Type: String
  LambdaCodeUriKey:
    Type: String

Resources:

  OnUpHealthLayer:
    Type: AWS::Lambda::LayerVersion
    Properties:
      CompatibleRuntimes:
      - python3.8
      Content:
        S3Bucket: !Sub '${LambdaCodeUriBucket}'
        S3Key: !Sub '${LambdaCodeUriKey}'

Create empty zip for the lambdas为 lambdas 创建空的 zip

Cloudformation must upload zip for lambdas, so we want it to create an empty zip. Cloudformation 必须为 lambda 上传 zip,因此我们希望它创建一个空的 zip。 But it scans the dependencies from the requirements.txt file in the directory the same as the one of template.yaml .但它会从与template.yaml相同的目录中的requirements.txt文件中扫描依赖项。 And we want it to upload something empty.我们希望它上传一些空的东西。 Hence it must be in another folder.因此它必须在另一个文件夹中。 To solve it, I copy the template.yaml to an empty directory and add empty requirements.txt file.为了解决这个问题,我将template.yaml复制到一个空目录并添加空的requirements.txt文件。 After that, we can run sam build and sam deploy as usuall.之后,我们可以像往常一样运行sam buildsam deploy Notice that we must pass it LambdaCodeUriBucket and LambdaCodeUriKey :请注意,我们必须传递给它LambdaCodeUriBucketLambdaCodeUriKey

#create "empty" environment for the template to be built in
mkdir -p .build/empty_template
cp template.yaml .build/empty_template
pushd .build/empty_template > /dev/null
touch requirements.txt
sam build --template template.yaml
sam deploy \
    --template-file .aws-sam/build/template.yaml \
    --capabilities "CAPABILITY_IAM" \
    --region $region \
    --s3-bucket $s3_bucket \
    --s3-prefix $s3_prefix \
    --stack-name $stack_name \
    --parameter-overrides LambdaCodeUriBucket=$s3_bucket LambdaCodeUriKey=$s3_lambda_zip_suffix
popd > /dev/null

Notice that although we copied the template.yaml and called sam build on the new one, we already uploaded to s3 the zip file.请注意,虽然我们复制了模板.yaml 并在新模板上调用了sam build ,但我们已经将 zip 文件上传到 s3。

Important thing you must do is specify .您必须做的重要事情是指定. as the CodeUri for your lambdas.作为您的 lambda 的CodeUri Because they now use the "empty zip".因为他们现在使用“空拉链”。

In the future, we will be able to do:未来,我们将能够做到:

InlineCode: |
    def handler(event, context):
        pass

And not specify folder .并且不指定文件夹. . .

But, currently sam doesn't support inline code for python3.8 hence we use .但是,目前sam不支持python3.8的内联代码,因此我们使用. . . Anyway you will have to move it to seperate folder to remove it's dependencies.无论如何,您必须将其移动到单独的文件夹以删除它的依赖项。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM