terraform-aws-modules/terraform-aws-lambda

Module always detect change even if src code doesn't change

Cesarsk opened this issue ยท 12 comments

Hello everyone.

The problem is simple. I have a configuration with this module, but at every 'terraform plan' it detect changes even though the src code hasn't changed at all.

Is there a way to fix the issue?

An example of my setup:

module "build" {
  source          = "terraform-aws-modules/lambda/aws"
  version         = "3.3.1"
  providers       = { aws = aws.account1 }
  create          = true
  create_package  = true
  create_function = false
  create_layer    = false
  create_role     = false
  store_on_s3     = true

  runtime       = "nodejs13.x"
  package_type  = "Zip"
  artifacts_dir = "."
  source_path   = [
    {
      path     = "../terraform/sg-reset-lambda/src"
      commands = [
        "npm install",
        ":zip ."
      ]
    }
  ]

  s3_object_storage_class = "STANDARD_IA"
  s3_bucket               = "RESERVED"
  s3_prefix               = "lambda-functions/"
  tags                    = var.common_tags
}


module "deploy" {
  source        = "terraform-aws-modules/lambda/aws"
  version       = "3.3.1"
  providers     = { aws = aws.account2 }
  function_name = "sg-reset"
  handler       = "index.handler"
  runtime       = "nodejs14.x"
  publish       = true
 

  create_package      = false
  s3_existing_package = {
    bucket     = RESERVED
    key        = RESERVED
    version_id = RESERVED
  }

  depends_on = [
    module.build
  ]
  tags = var.common_tags
}

Nobody's faced this issue so far?

Seeing the same behaviour

Seeing the same behaviour

Let's wait for other people, it's pretty annoying because I don't want that terraform deploys every time even if the src doesn't change.

image

I have this issue, or at least a very similar one - I use the archive_file resource to just create a dummy zip with an empty txt file in it just so I can create the lambda skeleton. Then I perform code updates and deployments using gitlab CI.

However, when I run terraform in CI-CD, as the dummy zip is generated in the different location, the filename changes, and thus it wants to re-deploy the function.. back as a dummy again. I had hoped the

ignore_source_code_hash = true
recreate_missing_package = false

Arguments would help but they don't seem to.

regarding the above, I think if the filename didn't use the full path (which can change based on execution environment) as part of calculating a change then this would not occur. To be honest i'm not sure if this is more a terraform issue itself or this module.

I've now gone with the below featuring a static dummy archive.

local_existing_package = "../../../lib/lambda_dummy.zip"

and now the file itself doesn't change location due to not being generated during terraform execution I don't see my issue, so back to the OP's query- mine isn't related.

@dc2tom I had the same issue in CI/CD context and rather than fighting with cache or any other persistency it is better to add ZIP creation just before calling terraform apply:

      - name: Prepare deployment package for Lambda
        working-directory: lambda
        run: |
          touch -t 202001010000 index.js
          zip -X deployment.zip index.js

then:

  create_package         = !var.install_deployment_zip
  source_path            = var.install_deployment_zip ? null : "${path.module}/lambda/index.js"
  local_existing_package = var.install_deployment_zip ? "${path.module}/lambda/deployment.zip" : null

so I can set install_deployment_zip = true in CD/CD and false in my CLI. A trick with touch and zip -X makes the same checksum for ZIP every time unless index.js changes.

I'm also hitting the same issue as I noticed that the data "external" "archive_prepare" will pass the full path to the query

      + query   = {
          + "artifacts_dir"            = "builds"
          + "docker"                   = null
          + "hash_extra"               = ""
          + "hash_extra_paths"         = jsonencode([])
          + "paths"                    = jsonencode(
                {
                  + cwd    = "/home/guido/redacted/.terragrunt-cache/uvI-qNDtOsZCtFWG5idKsIlf5hY/cagD491OY2cPvoQG1hjtA-vhqok/root"
                  + module = ".terraform/modules/user_files.origin_response"
                  + root   = "."
                }
            )
          + "recreate_missing_package" = "true"
          + "runtime"                  = "nodejs16.x"
          + "source_path"              = jsonencode(
                [
                  + {
                      + commands         = [
                          + "rm -rf ./node_modules",
                          + "rm -rf ./dist",
                          + "yarn install --frozen-lockfile",

Is there any way to fix this issue other than building the package outside of the module @antonbabenko ?

petur commented

I'm seeing this problem when using this module through terragrunt. It seems that terragrunt creates a file in the source directory named .terragrunt-source-manifest and this file contains an absolute path and maybe some other information that constantly differs.

Since my lambda only has a single source file, I'm fixing it by setting the filename as the source_path instead of the directory, but it would be useful if there was a way to exclude files from the content hash. The pattern seems to almost do what I need, but it seems that it is only filters the files added to the zip, extra files are still included in the hash.

I noticed that terragrunt will add that file but I have excluded it via the use of patterns too. I enabled debug logging and saw every single file being added to the zip and none of them are terragrunt related. The problem is that it reports there are changes when running through GitHub Actions since the runner directory is different.

GitHub Actions:

          + "paths"                    = jsonencode(
                {
                  + cwd    = "/home/runner/work/infrastructure/infrastructure/terraform/accounts/dev/.terragrunt-cache/zK12kk_BcoQpOX4MZiCGXiiLwXI/coFxVnD84wyfeIjEcs6QWOJTNoY/root"
                  + module = ".terraform/modules/user_files.origin_response"
                  + root   = "."
                }
            )

Local Machine:

          + "paths"                    = jsonencode(
                {
                  + cwd    = "/home/guido/redacted/.terragrunt-cache/uvI-qNDtOsZCtFWG5idKsIlf5hY/cagD491OY2cPvoQG1hjtA-vhqok/root"
                  + module = ".terraform/modules/user_files.origin_response"
                  + root   = "."
                }
            )

This issue has been automatically marked as stale because it has been open 30 days
with no activity. Remove stale label or comment or this issue will be closed in 10 days

This issue was automatically closed because of stale in 10 days

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.