为什么 Lambda 仍在使用 S3 存储桶中的旧版本 zip 文件?

Why Lambda still using the old version of the zip file in S3 bucket?

我正在使用 Terraform 创建一个 lambda 和一个 S3 存储桶,lambda 使用的二进制文件存储在这个存储桶中,在我更改二进制文件的内容后,lambda 似乎仍在使用文件的旧版本(我覆盖了桶中的文件),如何告诉lambda使用桶中文件的最新版本?

Lambda 函数不会因为S3 存储桶中的文件发生更改而更新。

类似于 AWS::Lambda::Function Code

中的 CloudFormation 想法

Changes to a deployment package in Amazon S3 are not detected automatically during stack updates. To update the function code, change the object key or version in the template.

根据我的理解,如果 Lambda 函数自动获取 S3 存储桶中的更改,我们将不知道我们正在执行什么 lambda 代码。作为适当的发布管理,我们应该能够明确发布新的 lambda 部署(最好避免使用 $LATEST 但发布)。

需要触发lambda函数更新。

一种方法是使用 aws_lambda_function Terraform 资源的 source_code_hash 属性,但文件需要是本地的,而不是在 S3 中,并且需要在 运行 terraform 应用之前更改.

或者更改 S3 存储桶对象位置并将新路径设置为 aws_lambda_function 的 s3_key 属性。例如对于每个新版本,创建一个新的 S3 文件夹 "v1"、"v2"、"v3",...并使用新文件夹(最好更新别名)。

resource "aws_lambda_function" "authorizer" {
  function_name    = "${var.lambda_authorizer_name}"
  source_code_hash = "${data.archive_file.lambda_authorizer.output_sha}" # <---
  s3_bucket        = "${aws_s3_bucket.package.bucket}"   
  s3_key           = "${aws_s3_bucket_object.lambda_authorizer_package.id}"   # <---

或者启用 S3 存储桶版本控制并更改 aws_lambda_function 的 s3_object_version 属性,或者使用 aws_s3_bucket_object 中的 version_id,或者在更改 S3 中的文件并检查之后版本号。

其中之一将触发更新调用 UpdateFunctionCode API as in resource_aws_lambda_function.go

func needsFunctionCodeUpdate(d resourceDiffer) bool {
    return d.HasChange("filename") || 
           d.HasChange("source_code_hash") || 
           d.HasChange("s3_bucket") || 
           d.HasChange("s3_key") || 
           d.HasChange("s3_object_version")
}

// UpdateFunctionCode in the API / SDK
func resourceAwsLambdaFunctionUpdate(d *schema.ResourceData, meta interface{}) error {
    conn := meta.(*AWSClient).lambdaconn

    ...
    codeUpdate := needsFunctionCodeUpdate(d)
    if codeUpdate {
        ...
        log.Printf("[DEBUG] Send Update Lambda Function Code request: %#v", codeReq)

        _, err := conn.UpdateFunctionCode(codeReq)
        if err != nil {
            return fmt.Errorf("Error modifying Lambda Function Code %s: %s", d.Id(), err)
        }
        ...
    }

或者,调用 AWS CLI update-function-code,这基本上是 terraform aws_lambda_function 代码所做的。