S3 存储桶中的 AWS Lambda 代码未更新

Posted

技术标签:

【中文标题】S3 存储桶中的 AWS Lambda 代码未更新【英文标题】:AWS Lambda Code in S3 Bucket not updating 【发布时间】:2018-05-05 16:37:53 【问题描述】:

我正在使用 cloudformation 来创建我的 lambda 函数,其中包含启用版本控制的 S3Bucket 中的代码。

"MYLAMBDA": 
      "Type": "AWS::Lambda::Function",
      "Properties": 
        "FunctionName": 
          "Fn::Sub": "My-Lambda-$StageName"
        ,
        "Code": 
          "S3Bucket": 
            "Fn::Sub": "$S3BucketName"
          ,
          "S3Key": 
            "Fn::Sub": "$artifact.zip"
          ,
          "S3ObjectVersion": "1e8Oasedk6sDZu6y01tioj8X._tAl3N"
        ,
        "Handler": "streams.lambda_handler",
        "Runtime": "python3.6",
        "Timeout": "300",
        "MemorySize": "512",
        "Role": 
          "Fn::GetAtt": [
            "LambdaExecutionRole",
            "Arn"
          ]
        
      
    

lambda 函数创建成功。当我将新的工件 zip 文件复制到 s3bucket 时,会使用新版本的“S3ObjectVersion”字符串创建文件的新版本。但是 lambda 函数代码仍然使用旧版本。

aws cloudformation 的文档清楚地说明了以下内容

更新源代码位于 Amazon S3 中的 Lambda 函数 存储桶,您必须通过更新 S3Bucket、S3Key 或 S3ObjectVersion 属性。单独更新源代码不会 更新函数。

是否有额外的触发事件,我需要创建以更新代码?

【问题讨论】:

我也有类似的问题,你找到解决办法了吗? 这里也一样。 Sam local 通过上传具有随机名称的工件并相应地修改模板来解决打包时的问题。不过,我不能使用它,因为嵌套模板尚不支持转换,而且我的 Lambda 是嵌套的。 我也有同样的问题。可以分享一下解决方法吗? 【参考方案1】:

如果有人遇到类似的问题,我已经找到了适合我的方法。我使用 Terraform + Jenkins 通过 s3 存储桶创建我的 lambda 函数。一开始,我可以创建函数,但一旦创建就不会更新。我验证了我在 s3 中的 zip 文件已更新。我花了一些时间才弄清楚我需要做以下两项更改之一。

解决方案 1:在加载新的 zip 文件时提供一个新的对象密钥。在我的 terraform 中,我将 git commit id 添加为 s3 密钥的一部分。

resource "aws_s3_bucket_object" "lambda-abc-package" 
  bucket = "$aws_s3_bucket.abc-bucket.id"
  key    = "$var.lambda_ecs_task_runner_bucket_key_$var.git_commit_id.zip"
  source = "../$var.lambda_ecs_task_runner_bucket_key.zip"

解决方案 2:在 lambda 部分添加 source_code_hash。

resource "aws_lambda_function" "abc-ecs-task-runner" 
  s3_bucket         = "$var.bucket_name"
  s3_key            = "$aws_s3_bucket_object.lambda-ecstaskrunner-package.key"
  function_name     = "abc-ecs-task-runner"
  role              = "$aws_iam_role.AbcEcsTaskRunnerRole.arn"
  handler           = "index.handler"
  memory_size       = "128"
  runtime           = "nodejs6.10"
  timeout           = "300"
  source_code_hash  = "$base64sha256(file("../$var.lambda_ecs_task_runner_bucket_key.zip"))"

所以任何一个都应该工作。此外,在检查 lambda 代码时,无法从浏览器刷新 URL。需要返回功能并再次打开该功能。

希望这会有所帮助。

【讨论】:

【参考方案2】:

我也遇到了同样的问题,我的代码在 S3 存储桶的 Archive.zip 中,当我上传新的 Archive.zip 时,lambda 没有根据新代码响应。

解决方案是再次将Archive.zip的S3位置链接粘贴到lambda的函数代码部分并再次保存。

我是如何发现 lambda 没有采用新代码的?

转到您的 lambda 函数 --> 操作 --> 导出函数 --> 下载部署包并检查代码是否真的是您最近上传到 S3 的代码。

【讨论】:

这也是我必须做的,但我想知道这是否是预期的行为,或者它是否应该每隔 x 时间自行更新,或者通过其他触发器。 【参考方案3】:

您必须将 S3ObjectVersion 值更新为 CloudFormation 模板本身中的新版本 ID。

然后您必须使用新模板更新您的 Cloudformation 堆栈。

您可以在 Cloudformation 控制台上或通过 AWS CLI 执行此操作。

【讨论】:

你有这方面的例子吗?这真是令人目瞪口呆。 好的,让我再试一次。 在 OP 的例子中,他有 "S3ObjectVersion": "1e8Oasedk6sDZu6y01tioj8X._tAl3N" 上传新的 zip 文件后,假设他得到了新版本 qwertyuiopasdfg2345jjQWERTY 。现在需要将模板行更新为"S3ObjectVersion": "qwertyuiopasdfg2345jjQWERTY"。假设更新的文件名是本地目录中的 template.json。好吧,AWS 不知道此模板更改,是吗?所以你再次运行这个命令aws cloudformation deploy --template-file /path_to_template/template.json。现在将采用新的更改 好的有道理。谢谢!我实际上发现这个问题是我们 CI 管道中的其他问题,但现在我也理解了这一点。 :) @Askdesigners 也会尽可能分享您的问题。祝你有美好的一天!

以上是关于S3 存储桶中的 AWS Lambda 代码未更新的主要内容,如果未能解决你的问题,请参考以下文章

AWS 云形成 |配置 Lambda 以使用 S3 存储桶中的最新版本代码

使用 aws lambda node js 获取存储在 s3 存储桶中的视频的视频元数据

使用 boto3 lib 和 AWS Lambda 从 S3 存储桶中的压缩文件中获取数据流

使用 AWS Lambda 在 S3 存储桶中更改文件

使用带有 Node.js 的 AWS Lambda 函数从 S3 存储桶中提取 zip 文件并上传到另一个存储桶

另一个账户中来自 Lambda 的 AWS 跨账户 S3 PutObject