amazon-web-services - 具有相同 CodeUri 的 AWS 多个 lambda
问题描述
我的 AWS 无服务器项目中有多个 lambda,它们都有相同的CodeUri
,这是我项目中的一个文件夹。例如,它们都指向src/
.
在基本用法中,或者至少在我使用它的方式中,该sam build
选项为每个 lambda 创建一个文件夹。所有文件夹都包含相同的代码。然后,在运行时,sam deploy
每个 zip 都会上传到 S3。拉链都是一样的,上传它们需要大量的冗余时间。
是否有“告诉”山姆只上传一次的选项?
我看到我可以手动构建 zip,然后将其上传到 S3。然后我怎样才能CodeUri
在 lambdas 中设置 uri?我应该使用外部参数还是有专门的方式来发出信号?
谢谢
解决方案
经过艰苦的努力,使用大卫康德的想法,我设法找到了一些解决方案。我们想要实现的是一次上传 lambda 的 zip(及其所有依赖项)并指向所有 lambda 以使用此 zip。
这个过程分为几个步骤,我将尽可能详细地描述这些步骤。其中一些可能与您的情况不完全相关。
大概的概念
一般的想法是创建一个包含我们要上传一次的代码的层。然后,对于每个 lambda,指定它使用该层。每个 lambda 都会让它的处理程序指向源目录中的某个位置。因此,“从层”运行代码。但!我们必须为 lambda 指定代码以运行/附加一个 zip——即使它不会运行。为了跳过它,我们将附加一个“空”代码。
构建文件夹
首先,创建一个我们将要工作的构建文件夹,例如:mkdir -p .build/
此外,定义以下变量:
s3_bucket="aaaaaaaa"
s3_prefix="aaaaaaaa"
s3_lambda_zip_suffix="$s3_prefix/lambda.zip"
s3_lambda_zip="s3://$s3_bucket/$s3_lambda_zip_suffix"
创建源 zip
解压缩 lambda 时,其内容将写入工作目录。解压缩层时,将/opt
按照 AWS 中的说明将其解压缩。因为我们的 lambda 需要找到我们的源代码,这是一个“依赖项”,它需要在/opt
. 为了实现它,我们需要将它解压缩到/opt/python
. 我们可以通过压缩python/...
成一个 zip 文件来做到这一点。
首先,我们创建文件夹,将依赖项安装到 python 文件夹中:
mkdir -p .build/lambda_zip/python
pip3 install -q --target .build/lambda_zip/python -r requirements.txt
然后我们压缩它:
pushd .build/lambda_zip/ > /dev/null
zip --quiet -r ./lambda.zip ./python
popd > /dev/null
现在,您可能想要添加您的 src 目录:
zip --quiet -r .build/lambda_zip/lambda.zip src
#Uploading to S3 现在,我们必须将 zip 文件上传到 S3 以便我们的 lambdas 加载它。
aws s3 cp ".build/lambda_zip/lambda.zip" $s3_lambda_zip_path
将图层添加到template.yaml
现在,我们需要将图层添加到我们的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}'
为 lambdas 创建空 zip
Cloudformation 必须为 lambdas 上传 zip,因此我们希望它创建一个空 zip。但它会从requirements.txt
目录中的文件中扫描依赖项,与template.yaml
. 我们希望它上传一些空的东西。因此它必须在另一个文件夹中。为了解决这个问题,我将它复制template.yaml
到一个空目录并添加空requirements.txt
文件。之后,我们可以sam build
像sam deploy
往常一样运行。请注意,我们必须通过它LambdaCodeUriBucket
并且LambdaCodeUriKey
:
#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
请注意,虽然我们复制了 template.yaml 并调用sam build
了新的,但我们已经将 zip 文件上传到 s3。
您必须做的重要事情是.
为CodeUri
您的 lambda 指定 。因为他们现在使用“空拉链”。
未来,我们将能够做到:
InlineCode: |
def handler(event, context):
pass
并且不指定文件夹.
。
但是,目前sam
不支持内联代码,python3.8
因此我们使用.
. 无论如何,您必须将其移动到单独的文件夹以删除它的依赖项。
推荐阅读
- python - 这是通过考虑python中相应列表的元素从列表中选择某个索引的合理方法吗?
- php - 当表达式作为闭包内数字数组的索引传递时,为什么PHP会抛出错误
- godot - GD 脚本。如何在 Godot 中创建自己的库并从游戏脚本中访问它
- java - 如何在 Java 开关中使用开关盒外的变量?
- php - 为什么此服务提供商的绑定不起作用?
- python - 安装kivy时出错
- firebase - Firebase 可调用函数,限制调用到 APP
- java - 如何在java中添加新记录?
- uml - 系统是否应该成为社交网络应用程序用例图中的参与者
- python - 在 Python 中使用用户的网格大小的表