使用boto3下载Lambda函数的部署包

Posted

技术标签:

【中文标题】使用boto3下载Lambda函数的部署包【英文标题】:Download the deployment package of Lambda function using boto3 【发布时间】:2022-01-03 17:24:21 【问题描述】:

我正在构建一个解决方案来管理 AWS Lambda 从一个区域/账户到另一个的迁移。 AWS 的 Lambda 控制面板目前只支持一次导出一个 Lambda,这对我来说太慢了。

我想使用 boto3 的 client.get_function(...)client.create_function(...) 来自动执行此操作。

Following the docs,我使用client.get_function("myFunc") 获取函数的配置和代码详细信息:

response = client.get_function(FunctionName = "myFunc")
fConfig = response["Configuration"]
fCode = response["Code"]
print(fCode)

>>> 'RepositoryType': 'S3',
    'Location': 'https://awslambda-us-east-2-tasks.s3.us-east-2.amazonaws.com/snapshots/1234567890123/myFunc-d6abcd8d-8a83...'

我的问题是如何使用fCode["Location"] 下载Lambda 的部署包,以便以后调用client.create_function(...) 时可以使用它?

我已阅读 boto3 S3 文档,但找不到任何可以帮助我的内容。只需点击“位置”链接即可返回:AccessDenied: No AWSAccessKey was presented.

如果有人可以解释一下response["Code"] 的用途。

【问题讨论】:

如果您创建一个clouformation模板或无服务器模板并使用它部署在不同的区域是不是容易得多? 【参考方案1】:

下面是一段将 Lambda 下载到本地机器上的 tmp 目录的 sn-p 代码。

import requests
import boto3
import json

lambda_client = boto3.client('lambda')

# Download the lambda
def download_lambda(function_arn):

   tmp_dir = '/tmp/' 
         
   arn = function_arn
   arn_parts = arn.split(':')
   func_name = arn_parts[6]
   
   func_details = lambda_client.get_function(FunctionName=function_arn)
   zip_file = tmp_dir + func_name + '.zip'
   url = func_details['Code']['Location']
   
   r = requests.get(url)
   with open(zip_file, "wb") as code:
      code.write(r.content)

【讨论】:

【参考方案2】:

根据文档,get_function 返回的 Location 返回一个预签名的 S3 URL。这意味着您应该可以通过GETing 这个 URL 来下载 zip 包。 然后,您可以使用 zip 作为 create_function 的输入。

我没有尝试过使用 boto,但是当我使用 AWS cli 的 aws lambda get-function --function-name <A_FUNCTION_NAME> 时,它的工作方式与描述的一样。我可以在浏览器中打开 URL 并能够下载函数的 zip。

对我来说,boto 使用的凭据/角色似乎不允许在资源上调用 s3:GetObject。

您可以试试它是否适用于 aws cli(确保使用与 boto 中相同的角色/用户)!?

【讨论】:

谢谢科尔根。使用我的主要 AWS 凭证从 CLI 调用它允许我下载文件而无需点击 AccessDenied: No AWSAccessKey was presented。所以我怀疑我在函数中使用的 IAM 凭证没有所需的用户权限。那么我的下一个问题是,我需要为这个用户附加什么权限? 我假设 S3 对象的 s3:GetObject 权限以及存储桶上的 s3:ListBucket 权限......虽然没有尝试过。 docs.aws.amazon.com/AmazonS3/latest/userguide/… 的文档说“任何拥有有效安全凭证的人都可以创建预签名 URL。但是,为了成功访问对象,预签名 URL 必须由有权执行预签名 URL 所基于的操作的人创建上。”【参考方案3】:

正如@Korgen 指出的那样,get_function 命令返回一个S3 presigned URL。

我已经成功地生成并使用了一个在 lambda 中使用 boto3 的下载 URL,它具有默认的基本执行角色和 get_function 权限。不需要其他权限(例如,没有 S3 权限)。

该网址可供任何人使用(例如,您可以将其粘贴到浏览器中)。但是,该 URL 会在 10 分钟后过期X-Amz-Expires=599 标头)。这是预签名 URL 的一个特性,它是公开的,但寿命很短。

【讨论】:

以上是关于使用boto3下载Lambda函数的部署包的主要内容,如果未能解决你的问题,请参考以下文章

如何增加 AWS lambda 部署包的最大大小 (RequestEntityTooLargeException)?

使用 Boto3 更新 Lambda 函数以使用新的层版本

在单个AWS Lambda中使用两个python函数boto3

函数 ec2.snapshots.all 不迭代 boto3 lambda

通过 Cloudformation、CodeBuild 和 CodePipeline 将 python 包部署到 AWS Lambda

如何使用 lambda 将 s3 中的最新代码部署到 lambda 函数