将 terraform 与 localstack 一起使用时如何挂载 lambda 代码?
How can I mount lambda code when using terraform with localstack?
TLDR
我如何在 terraform 中配置我的提供程序,以便它使用 docker 挂载代码和正确的函数目录来执行 lambda 函数?
我正在尝试 运行 一个简单的 lambda 函数来侦听 dynamodb 流事件。我的代码本身工作正常,但我遇到的问题是在使用 terraform 时,函数执行器找不到 运行 的函数。为了调试,我在本地堆栈容器 DEBUG=true
中设置了以下 envars。我首先使用无服务器框架测试了我的代码,它按预期工作。
无服务器的成功函数执行日志显示:
localstack | 2021-03-17T13:14:53:INFO:localstack.services.awslambda.lambda_executors: Running lambda cmd: docker run -i -v "/Users/myuser/functions":/var/task -e AWS_REGION="$AWS_REGION" -e DOCKER_LAMBDA_USE_STDIN="$DOCKER_LAMBDA_USE_STDIN" -e LOCALSTACK_HOSTNAME="$LOCALSTACK_HOSTNAME" -e EDGE_PORT="$EDGE_PORT" -e _HANDLER="$_HANDLER" -e AWS_LAMBDA_FUNCTION_TIMEOUT="$AWS_LAMBDA_FUNCTION_TIMEOUT" -e AWS_LAMBDA_FUNCTION_NAME="$AWS_LAMBDA_FUNCTION_NAME" -e AWS_LAMBDA_FUNCTION_VERSION="$AWS_LAMBDA_FUNCTION_VERSION" -eAWS_LAMBDA_FUNCTION_INVOKED_ARN="$AWS_LAMBDA_FUNCTION_INVOKED_ARN" -e AWS_LAMBDA_COGNITO_IDENTITY="$AWS_LAMBDA_COGNITO_IDENTITY" --rm "lambci/lambda:go1.x" "bin/dbchanges"
localstack | 2021-03-17T13:14:54:DEBUG:localstack.services.awslambda.lambda_executors: Lambda arn:aws:lambda:us-east-1:000000000000:function:myService-local-dbchanges result / log output:
localstack | null
Terraform:问题
但是当从 terramform 中 运行ning 时,看起来函数找不到并且失败并显示以下日志:
localstack | 2021-03-17T13:30:32:INFO:localstack.services.awslambda.lambda_executors: Running lambda cmd: docker run -i -v "/tmp//zipfile.717163a0":/var/task -e AWS_REGION="$AWS_REGION" -e DOCKER_LAMBDA_USE_STDIN="$DOCKER_LAMBDA_USE_STDIN" -e LOCALSTACK_HOSTNAME="$LOCALSTACK_HOSTNAME" -e EDGE_PORT="$EDGE_PORT" -e _HANDLER="$_HANDLER" -e AWS_LAMBDA_FUNCTION_TIMEOUT="$AWS_LAMBDA_FUNCTION_TIMEOUT" -e AWS_LAMBDA_FUNCTION_NAME="$AWS_LAMBDA_FUNCTION_NAME" -e AWS_LAMBDA_FUNCTION_VERSION="$AWS_LAMBDA_FUNCTION_VERSION" -e AWS_LAMBDA_FUNCTION_INVOKED_ARN="$AWS_LAMBDA_FUNCTION_INVOKED_ARN" -e AWS_LAMBDA_COGNITO_IDENTITY="$AWS_LAMBDA_COGNITO_IDENTITY" --rm "lambci/lambda:go1.x" "dbchanges"
localstack | 2021-03-17T13:30:33:DEBUG:localstack.services.awslambda.lambda_executors: Lambda arn:aws:lambda:us-east-1:000000000000:function:dbchanges result / log output:
localstack | {"errorType":"exitError","errorMessage":"RequestId: 4f3cfd0a-7905-12e2-7d4e-049bd2c1a1ac Error: fork/exec /var/task/dbchanges: no such file or directory"}
检查两个日志集后,我注意到 terraform + localstack docker 执行器挂载的路径不同。在无服务器的情况下,它指向正确的文件夹以进行卷安装;即 /Users/myuser/functions
在 terraform 中,它正在安装 /tmp//zipfile.somevalue
这似乎是问题的根源。
在我的无服务器配置文件中,lambda mountcode 设置为 true,这让我相信这就是它正确挂载和执行的原因。
lambda:
mountCode: True
所以我的问题是,我可以在 terraform 中做什么,以便上传的函数实际上由 docker 容器执行,或者告诉 terraform 挂载正确的目录以便它可以找到该函数?我的 terraform lambda 函数定义是:
data "archive_file" "dbchangeszip" {
type = "zip"
source_file = "../bin/dbchanges"
output_path = "./zips/dbchanges.zip"
}
resource "aws_lambda_function" "dbchanges" {
description = "Function to capture dynamodb change"
runtime = var.runtime
timeout = var.timeout
memory_size = var.memory
role = aws_iam_role.lambda_role.arn
handler = "dbchanges"
filename = "./zips/dbchanges.zip"
function_name = "dbchanges"
source_code_hash = data.archive_file.dbchangeszip.output_base64sha256
}
P.S。其他一些尝试是
- 将 terraform 中的处理程序设置为
bin/handler
以模仿无服务器
解决了问题。使用 terraform 时,未定义用于存储函数的 s3 存储桶,因此必须在 terraform 的资源定义中设置这两个存储桶。
示例:
resource "aws_lambda_function" "dbchanges" {
s3_bucket = "__local__"
s3_key = "/Users/myuser/functions/"
role = aws_iam_role.lambda_role.arn
handler = "bin/dbchanges"
# filename = "./zips/dbchanges.zip"
function_name = "dbchanges"
source_code_hash = data.archive_file.dbchangeszip.output_base64sha256
}
两个重要的值是:
s3_bucket = "__local__"
s3_key = "/Users/myuser/functions/"
其中 s3_key
是函数的绝对路径。
TLDR
我如何在 terraform 中配置我的提供程序,以便它使用 docker 挂载代码和正确的函数目录来执行 lambda 函数?
我正在尝试 运行 一个简单的 lambda 函数来侦听 dynamodb 流事件。我的代码本身工作正常,但我遇到的问题是在使用 terraform 时,函数执行器找不到 运行 的函数。为了调试,我在本地堆栈容器 DEBUG=true
中设置了以下 envars。我首先使用无服务器框架测试了我的代码,它按预期工作。
无服务器的成功函数执行日志显示:
localstack | 2021-03-17T13:14:53:INFO:localstack.services.awslambda.lambda_executors: Running lambda cmd: docker run -i -v "/Users/myuser/functions":/var/task -e AWS_REGION="$AWS_REGION" -e DOCKER_LAMBDA_USE_STDIN="$DOCKER_LAMBDA_USE_STDIN" -e LOCALSTACK_HOSTNAME="$LOCALSTACK_HOSTNAME" -e EDGE_PORT="$EDGE_PORT" -e _HANDLER="$_HANDLER" -e AWS_LAMBDA_FUNCTION_TIMEOUT="$AWS_LAMBDA_FUNCTION_TIMEOUT" -e AWS_LAMBDA_FUNCTION_NAME="$AWS_LAMBDA_FUNCTION_NAME" -e AWS_LAMBDA_FUNCTION_VERSION="$AWS_LAMBDA_FUNCTION_VERSION" -eAWS_LAMBDA_FUNCTION_INVOKED_ARN="$AWS_LAMBDA_FUNCTION_INVOKED_ARN" -e AWS_LAMBDA_COGNITO_IDENTITY="$AWS_LAMBDA_COGNITO_IDENTITY" --rm "lambci/lambda:go1.x" "bin/dbchanges"
localstack | 2021-03-17T13:14:54:DEBUG:localstack.services.awslambda.lambda_executors: Lambda arn:aws:lambda:us-east-1:000000000000:function:myService-local-dbchanges result / log output:
localstack | null
Terraform:问题
但是当从 terramform 中 运行ning 时,看起来函数找不到并且失败并显示以下日志:
localstack | 2021-03-17T13:30:32:INFO:localstack.services.awslambda.lambda_executors: Running lambda cmd: docker run -i -v "/tmp//zipfile.717163a0":/var/task -e AWS_REGION="$AWS_REGION" -e DOCKER_LAMBDA_USE_STDIN="$DOCKER_LAMBDA_USE_STDIN" -e LOCALSTACK_HOSTNAME="$LOCALSTACK_HOSTNAME" -e EDGE_PORT="$EDGE_PORT" -e _HANDLER="$_HANDLER" -e AWS_LAMBDA_FUNCTION_TIMEOUT="$AWS_LAMBDA_FUNCTION_TIMEOUT" -e AWS_LAMBDA_FUNCTION_NAME="$AWS_LAMBDA_FUNCTION_NAME" -e AWS_LAMBDA_FUNCTION_VERSION="$AWS_LAMBDA_FUNCTION_VERSION" -e AWS_LAMBDA_FUNCTION_INVOKED_ARN="$AWS_LAMBDA_FUNCTION_INVOKED_ARN" -e AWS_LAMBDA_COGNITO_IDENTITY="$AWS_LAMBDA_COGNITO_IDENTITY" --rm "lambci/lambda:go1.x" "dbchanges"
localstack | 2021-03-17T13:30:33:DEBUG:localstack.services.awslambda.lambda_executors: Lambda arn:aws:lambda:us-east-1:000000000000:function:dbchanges result / log output:
localstack | {"errorType":"exitError","errorMessage":"RequestId: 4f3cfd0a-7905-12e2-7d4e-049bd2c1a1ac Error: fork/exec /var/task/dbchanges: no such file or directory"}
检查两个日志集后,我注意到 terraform + localstack docker 执行器挂载的路径不同。在无服务器的情况下,它指向正确的文件夹以进行卷安装;即 /Users/myuser/functions
在 terraform 中,它正在安装 /tmp//zipfile.somevalue
这似乎是问题的根源。
在我的无服务器配置文件中,lambda mountcode 设置为 true,这让我相信这就是它正确挂载和执行的原因。
lambda:
mountCode: True
所以我的问题是,我可以在 terraform 中做什么,以便上传的函数实际上由 docker 容器执行,或者告诉 terraform 挂载正确的目录以便它可以找到该函数?我的 terraform lambda 函数定义是:
data "archive_file" "dbchangeszip" {
type = "zip"
source_file = "../bin/dbchanges"
output_path = "./zips/dbchanges.zip"
}
resource "aws_lambda_function" "dbchanges" {
description = "Function to capture dynamodb change"
runtime = var.runtime
timeout = var.timeout
memory_size = var.memory
role = aws_iam_role.lambda_role.arn
handler = "dbchanges"
filename = "./zips/dbchanges.zip"
function_name = "dbchanges"
source_code_hash = data.archive_file.dbchangeszip.output_base64sha256
}
P.S。其他一些尝试是
- 将 terraform 中的处理程序设置为
bin/handler
以模仿无服务器
解决了问题。使用 terraform 时,未定义用于存储函数的 s3 存储桶,因此必须在 terraform 的资源定义中设置这两个存储桶。
示例:
resource "aws_lambda_function" "dbchanges" {
s3_bucket = "__local__"
s3_key = "/Users/myuser/functions/"
role = aws_iam_role.lambda_role.arn
handler = "bin/dbchanges"
# filename = "./zips/dbchanges.zip"
function_name = "dbchanges"
source_code_hash = data.archive_file.dbchangeszip.output_base64sha256
}
两个重要的值是:
s3_bucket = "__local__"
s3_key = "/Users/myuser/functions/"
其中 s3_key
是函数的绝对路径。