I'm trying to deploy an AWS Lambda function using Terragrunt without attaching a zip package. The goal is to create the function with basic configurations and manage it directly through Terragrunt.
I've attempted setting create_package: false but Terragrunt throws an error Could not locate source_path "null". I tried using a dummy package with local_existing_package: "./dummy.zip" and ignore_source_code_hash: true, but the error persists.
Here’s what my configuration looks like:
1st Try:
- function_name: test-function
create_package: false
description: "test-function"
handler: "lambda_handler"
2nd Try:
- function_name: test-function
create_package: false
local_existing_package: "./dummy.zip"
ignore_source_code_hash: true
description: "test-function"
handler: "lambda_handler"
I believe this configuration should work:
- function_name: test-function
create_package: false
local_existing_package: "./dummy.zip"
ignore_source_code_hash: true
description: "test-function"
handler: "lambda_handler"
runtime: "python3.9"
memory_size: 128
but there's one thing that concerns me, the local_existing_package should be the absolute path not the relative path.
variable "local_existing_package" {
description = "The absolute path to an existing zip-file to use"
type = string
default = null
}
so try to use local_existing_package = "${abspath("./dummy.zip")}"
instead
and clear the terragrunt cache before applying again :
rm -rf .terragrunt-cache
Solution
The issue was in the lambdas = try({}) block. Initially, only the function_name and options were being passed, while everything else was ignored.
After encountering the error (source_path "null"), I decided to debug the actual inputs being sent to the Lambda module. To do this, I added the following line:
debug_input_items = run_cmd("echo", "DEBUG: Items passed to module -> ${jsonencode(local.lambdas)}")
To my surprise, the debug revealed that only the function_name was being passed to the module. This explained why source_path was still null even when I explicitly set it to “something.”
To fix this, I updated the block to include all the necessary fields like runtime, handler, memory_size, and others. Additionally, because .hcl files don’t support $ for interpolation, I ensured that local_existing_package was handled dynamically by constructing its path based on the Lambda function name. Since you’ll typically use the same name for the ZIP file as the Lambda function, this approach simplifies the setup.
Here’s the updated block:
lambdas = try({
for lambda in local.all_lambdas:
"${include.root.locals.convention-naming}-${lambda.function_name}" => merge(
{
function_name = "${include.root.locals.convention-naming}-${lambda.function_name}"
create_package = lambda.create_package
local_existing_package = abspath("${get_terragrunt_dir()}/${lambda.function_name}.zip")
ignore_source_code_hash = lambda.ignore_source_code_hash
description = lambda.description
handler = lambda.handler
runtime = lambda.runtime
memory_size = lambda.memory_size
},
try(lambda.options, {}) # Include optional configurations
)
}, {})
debug_input_items = run_cmd("echo", "DEBUG: Items passed to module -> ${jsonencode(local.lambdas)}")
I tested everything at my end and it's working. Do not forget to add a non empty .py file within the zip file. just python file with print('Hello World!') will be enough
Thank you for uploading out the code and sorry for being a little bit late.