terraform-aws-modules / terraform-aws-lambda

Terraform module, which takes care of a lot of AWS Lambda/serverless tasks (build dependencies, packages, updates, deployments) in countless combinations 🇺🇦
https://registry.terraform.io/modules/terraform-aws-modules/lambda/aws
Apache License 2.0
892 stars 662 forks source link

Output local_filename is available _before_ the package is available #355

Closed lorengordon closed 1 year ago

lorengordon commented 1 year ago

Description

I was attempting to build the package locally once, and then use it several times in different lambda functions. That ends up looking something like this:

module "test_create_package" {
  source = "git::https://github.com/terraform-aws-modules/terraform-aws-lambda.git?ref=v4.0.2"

  create_function = false
  create_package  = true

  recreate_missing_package = false

  runtime     = "python3.8"
  source_path = "${path.module}/../../lambda/src"
}

module "test_create_function" {
  source = "git::https://github.com/terraform-aws-modules/terraform-aws-lambda.git?ref=v4.0.2"

  function_name = "foo"
  handler       = "index.lambda_handler"
  runtime       = "python3.8"

  create_package = false
  local_existing_package = module.test_create_package.local_filename
}

The problem is that the output local_filename is determined immediately at plan time, but the zip is only created in the apply phase. Which means the terraform graph determines that it is able to use the value immediately in the apply phase to create the lambda function. Which results in errors of the form:

│ Error: unable to load "./builds/4d797a72c1bf2fcf10fcee1ece41ecf3e1ec6c99ea87c4772711bc449c5bad4b.zip": open ./builds/4d797a72c1bf2fcf10fcee1ece41ecf3e1ec6c99ea87c4772711bc449c5bad4b.zip: no such file or directory
│
│   with module.test_create_function.module.lambda.aws_lambda_function.this[0],
│   on .terraform/modules/test_create_function.lambda/main.tf line 22, in resource "aws_lambda_function" "this":
│   22: resource "aws_lambda_function" "this" {

I believe this can be fixed by adding a depends_on statement to the output local_filename for null_resource.archive:

output "local_filename" {
  description = "The filename of zip archive deployed (if deployment was from local)"
  value       = local.filename

  depends_on = [
    null_resource.archive,
  ]
}

I'll be testing that and opening a pull request shortly if it does indeed fix the behavoir.

antonbabenko commented 1 year ago

Not sure if depends_on between modules will help with this. Worth trying.

route53 module has such a solution already.

lorengordon commented 1 year ago

Yes, that is also an option, but module-level depends_on does some ugly things to the graph. Forcing the output to wait keeps the graph really clean.

lorengordon commented 1 year ago

And I did just test my fork with this change and it does indeed fix the problem...

antonbabenko commented 1 year ago

This issue has been resolved in version 4.1.1 :tada:

github-actions[bot] commented 1 year ago

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues. If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.