Terraform没有上传新的ZIP

时间:2018-12-20 07:59:53

标签: amazon-web-services aws-lambda terraform

我想使用Terraform来部署我的lambda函数。我做了类似的事情:

provider "aws" {
    region = "ap-southeast-1"
}

data "archive_file" "lambda_zip" {
    type = "zip"
    source_dir = "src"
    output_path = "build/lambdas.zip"
}

resource "aws_lambda_function" "test_terraform_function" {
    filename = "build/lambdas.zip"
    function_name = "test_terraform_function"
    handler = "test.handler"
    runtime = "nodejs8.10"
    role = "arn:aws:iam::000000000:role/xxx-lambda-basic"
    memory_size = 128
    timeout = 5
    source_code_hash = "${data.archive_file.lambda_zip.output_base64sha256}"
    tags = {
        "Cost Center" = "Consulting"
        Developer = "Jiew Meng"
    }
}

我发现当test.js没有变化时,terraform可以正确检测到没有变化

No changes. Infrastructure is up-to-date.

当我更改test.js文件时,terraform会检测到更改:

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  ~ aws_lambda_function.test_terraform_function
      last_modified:    "2018-12-20T07:47:16.888+0000" => <computed>
      source_code_hash: "KpnhsytFF0yul6iESDCXiD2jl/LI9dv56SIJnwEi/hY=" => "JWIYsT8SszUjKEe1aVDY/ZWBVfrZYhhb1GrJL26rYdI="

它确实压缩了新的zip,但是,它似乎并未使用新的ZIP来更新功能。由于文件名没有更改,因此它似乎没有上载,因此认为...我该如何解决此问题?

=====

在这里回答一些之后,我尝试了:

  • 使用null_resource
  • 使用带有etag的S3存储桶/对象

并且它不会更新...那是为什么?

4 个答案:

答案 0 :(得分:5)

我遇到了同样的问题,为我解决的问题是使用publish argument自动发布Lambda函数。为此,只需在您的publish = true资源中设置aws_lambda_function

请注意,此后将对您的函数进行版本控制,每次更改都会创建一个新的函数。因此,如果要在任何其他Terraform代码中引用该函数,则应确保使用qualified_arn属性引用。

答案 1 :(得分:2)

如果目标Lambda文件名是src/main.pysrc/handler.py,则有一种变通方法可以触发刷新资源。如果您还有更多文件要管理,请一一添加。

resource "null_resource" "lambda" {
  triggers {
    main    = "${base64sha256(file("src/main.py"))}"
    handler = "${base64sha256(file("src/handler.py"))}"
  }
}

data "archive_file" "lambda_zip" {
  type        = "zip"
  source_dir  = "src"
  output_path = "build/lambdas.zip"

  depends_on = ["null_resource.lambda"]
}

让我知道这是否对您有用。

答案 2 :(得分:2)

您需要注意两件事:

  • 如果内容已更改,则将zip文件上传到S3
  • 如果zip文件内容已更改,请更新Lambda函数

我可以看到您正在使用source_code_hash来照顾后者。我看不出您如何处理前者。看起来像这样:

resource "aws_s3_bucket_object" "zip" {
  bucket               = "${aws_s3_bucket.zip.bucket}"
  key                  = "myzip.zip"
  source               = "${path.module}/myzip.zip"
  etag                 = "${md5(file("${path.module}/myzip.zip"))}"
}

etag是这里最重要的选项。

答案 3 :(得分:0)

我创建了此模块来帮助缓解有关通过Terraform部署Lambda的一些问题:https://registry.terraform.io/modules/rojopolis/lambda-python-archive/aws/0.1.4

在这种情况下可能有用。基本上,它将“ archive_file”数据源替换为专用的lambda存档数据源,以更好地管理稳定的源代码哈希等。