terraform-aws-modules/terraform-aws-lambda

Zip command ignores the "source" parameter

gp42 opened this issue · 10 comments

gp42 commented

Description

Starting with version v7.2.6 ":zip" ignores the source parameter.

This works as expected on version v7.2.5 - lambda only contains files from the build folder in function root /.
Starting with v7.2.6 this is not the case anymore, and all files from the path are added to the package.

  • ✋ I have searched the open/closed issues and my issue is not listed.

Versions

  • Module version [Required]: v7.2.6
  • Terraform version: v1.7.2
  • Provider version(s): hashicorp/aws v5.45.0

Reproduction Code [Required]

...
  build_in_docker = false
  source_path = [
    {
      path = "${path.module}/files/lambda"
      commands = [
        ":zip build /"
      ],
    }
  ]

Steps to reproduce the behavior:

Use :zip command with source and destination parameters to copy files from subdirectory.

Expected behavior

Function package only contains Files from source directory in destination.

Actual behavior

All files from path are present in function package.

Additional context

Bug introduced in v7.2.6

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

I am also affected by this bug, and am hoping it isn't auto-closed.

+1 on this, all of a sudden the deployment seems to pack the entire folder, not just the build directory on me end too.

source_path = [
    {
      path = "${path.module}/../backend/lambda/my-lambda",
      commands = [
        "pnpm install",
        "pnpm run build",
        ":zip dist ."
      ]
    }
  ]

@tonio-ramirez did you find a workaround for the time being?

Workaround we had to go with was

source_path = [
    {
      path = "${path.module}/../backend/lambda/my-lambda",
      commands = [
        "pnpm install",
        "pnpm run build",
        "cd dist",
        ":zip"
      ]
    }
  ]

Wonder if is a bug introduced in comit: (f786681) in package.py:935 added line -
sh_work_dir = temp_file.read().strip()
which sets variable sh_work_dir to be the present working directory pwd of the execution context.
This then becomes dominant over the specified source_path of the command (even if it is specified) at package.py:886-889

                if sh_work_dir:
                    if source_path != sh_work_dir:
                        if not os.path.isfile(source_path):
                            source_path = sh_work_dir

this is then successfully worked around by @anuradhawick's cd dist

While trying to figure out why the patterns arg wasn't working I also noticed that the filter doesn't actually work as well.

The problem seems to be that ZipContentFilter.filter.apply sets the default return value to True (add the file to the zip archive). If the tested file isn't matched by the rule we don't update the return value d.

I think the fix could look something like this (if there are no rules add the file by default; if there are rules default to not adding it and only add it if there is an explicit match)

diff --git a/package.py b/package.py
index ded4056..093ef78 100644
--- a/package.py
+++ b/package.py
@@ -587,20 +587,22 @@ class ZipContentFilter:
         def apply(path):
-            d = True
+            d = len(rules) == 0
             for r in rules:
                 op, regex = r
                 neg = op is operator.not_
                 m = regex.fullmatch(path)
                 if neg and m:
                     d = False
                 elif m:
                     d = True
             if d:
                 return path

I finally figured out a nice way to work around this without having to cd into the dist directory (which created constant drifts for me)

If you set patterns to first ignore everything (which triggers the if neg and m path and causes the default to be False and then in a second pattern only match the files you actually need it works as expected

[ "!.*", "^/dist/index.cjs$"]