如何用Terraform打包含通用工具函数的Python Lambda函数?
针对Python Lambda + Terraform 打包含通用工具函数的方案
方案1:直接用archive_file关联Lambda源码和codelib目录
针对每个Lambda函数,你可以在archive_file资源中同时指定Lambda自身的源码目录和codelib目录,确保打包后的Zip文件保留正确的目录结构,让Python能正常导入工具函数。
假设你的目录结构如下:
src/ ├── codelib/ │ └── helper_util_fn.py ├── lambda_func1/ │ └── main.py └── lambda_func2/ └── main.py
以lambda_func1为例,对应的Terraform代码:
resource "archive_file" "lambda_func1_zip" { type = "zip" output_path = "${path.module}/build/lambda_func1.zip" # 同时包含Lambda自身源码目录和codelib目录 source_dirs = [ "${path.module}/src/lambda_func1", "${path.module}/src/codelib" ] }
打包后的Zip内部结构为:
lambda_func1.zip/ ├── main.py └── codelib/ └── helper_util_fn.py
Lambda执行时,直接用from codelib.helper_util_fn import xxx就能正确导入工具函数。
如果需要精细控制文件(比如排除临时文件),可以结合fileset和source_files实现:
resource "archive_file" "lambda_func1_zip" { type = "zip" output_path = "${path.module}/build/lambda_func1.zip" source_files = [ # 导入Lambda目录下所有Python文件 for file in fileset("${path.module}/src/lambda_func1", "*.py") : "${path.module}/src/lambda_func1/${file}", # 导入codelib目录下所有Python文件 for file in fileset("${path.module}/src/codelib", "*.py") : "${path.module}/src/codelib/${file}" ] # 保持文件相对目录结构,确保导入路径正确 source_content_filename = { for file in fileset("${path.module}/src/lambda_func1", "*.py") : "${path.module}/src/lambda_func1/${file}" => file } source_content_filename += { for file in fileset("${path.module}/src/codelib", "*.py") : "${path.module}/src/codelib/${file}" => "codelib/${file}" } }
方案2:用source_dir按目录层级处理
如果倾向于用source_dir属性,需要先把codelib目录复制到Lambda函数的目录下,再以Lambda目录作为打包源。可以用null_resource配合本地命令实现:
# 先将codelib复制到Lambda函数目录 resource "null_resource" "copy_codelib_to_lambda1" { triggers = { # 当Lambda源码或codelib文件变化时触发复制操作 lambda_files = sha1(join("", fileset("${path.module}/src/lambda_func1", "**/*"))) codelib_files = sha1(join("", fileset("${path.module}/src/codelib", "**/*"))) } provisioner "local-exec" { # Linux/macOS环境命令 command = "cp -r ${path.module}/src/codelib ${path.module}/src/lambda_func1/" # Windows环境替换为: # command = "robocopy ${path.module}/src/codelib ${path.module}/src/lambda_func1/codelib /E" } } # 以包含codelib的Lambda目录作为source_dir打包 resource "archive_file" "lambda_func1_zip" { type = "zip" output_path = "${path.module}/build/lambda_func1.zip" source_dir = "${path.module}/src/lambda_func1" # 依赖复制操作完成后再打包 depends_on = [null_resource.copy_codelib_to_lambda1] }
注意:这种方式会修改本地Lambda源码目录,建议把Lambda目录下的codelib加入.gitignore,避免提交冗余文件。
额外提示
- 两种方案都要保证Zip内部的目录结构符合Python导入规则,即codelib要和Lambda主文件处于同一层级。
- 可以把打包逻辑抽象成Terraform模块,避免每个Lambda重复编写相同代码。
内容的提问来源于stack exchange,提问作者Abhi
相关产品推荐
相关产品推荐

