Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Terraform not uploading a new ZIP

I want to use Terraform for deployment of my lambda functions. I did something like:

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"
    }
}

I find that when there is no change to test.js, terraform correctly detects no change

No changes. Infrastructure is up-to-date.

When I do change the test.js file, terraform does detect a change:

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="

It does zip up the new zip, however, it does not seem to update the function with the new ZIP. It seems like it thinks since the filename has no change, it does not upload ... How can I fix this behaviour?

=====

Following some of the answers here, I tried:

  • Using null_resource
  • Using S3 bucket/object with etag

And it does not update ... Why is that?

like image 306
Jiew Meng Avatar asked Dec 20 '18 07:12

Jiew Meng


2 Answers

I ran into the same issue and what solved it for me was publishing the Lambda functions automatically using the publish argument. To do so simply set publish = true in your aws_lambda_function resource.

Note that your function will be versioned after this and each change will create a new one. Therefor you should make sure that you use the qualified_arn attribute reference if you're referring to the function in any of your other Terraform code.

like image 56
Karl Laurentius Roos Avatar answered Oct 05 '22 03:10

Karl Laurentius Roos


There is a workaround to trigger the resource to be refreshed, if the target lambda file names are src/main.py and src/handler.py. If you have more files to be managed, add them one by one.

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"]
}

Let me know if this works for you.

like image 40
BMW Avatar answered Oct 05 '22 01:10

BMW