使用 terraform 设置由计划事件源触发的 lambda 函数
Use terraform to set up a lambda function triggered by a scheduled event source
我想每五分钟 运行 一个 AWS lambda 函数。在 AWS 管理控制台中,这很容易设置,在 lambda 函数的 "Event Sources" 选项卡下,但如何使用 Terraform?
进行设置
我尝试使用 an aws_lambda_event_source_mapping
resource, but it turns out that the API it uses 仅支持来自 Kinesis 和 DynamoDB 的事件。当我尝试将它与计划的事件源一起使用时,创建超时。
您可以使用 aws_cloudwatch_event_target
资源将计划的事件源(事件规则)绑定到您的 lambda 函数。您需要授予它调用您的 lambda 函数的权限;您可以为此使用 aws_lambda_permission
资源。
示例:
resource "aws_lambda_function" "check_foo" {
filename = "check_foo.zip"
function_name = "checkFoo"
role = "arn:aws:iam::424242:role/something"
handler = "index.handler"
}
resource "aws_cloudwatch_event_rule" "every_five_minutes" {
name = "every-five-minutes"
description = "Fires every five minutes"
schedule_expression = "rate(5 minutes)"
}
resource "aws_cloudwatch_event_target" "check_foo_every_five_minutes" {
rule = aws_cloudwatch_event_rule.every_five_minutes.name
target_id = "check_foo"
arn = aws_lambda_function.check_foo.arn
}
resource "aws_lambda_permission" "allow_cloudwatch_to_call_check_foo" {
statement_id = "AllowExecutionFromCloudWatch"
action = "lambda:InvokeFunction"
function_name = aws_lambda_function.check_foo.function_name
principal = "events.amazonaws.com"
source_arn = aws_cloudwatch_event_rule.every_five_minutes.arn
}
Verbjorns Ljosa 的回答仅包含 cloudwatch 调用 lambda 的权限。您是否指定了允许 lambda 执行其操作的适当策略和 iam 角色?
resource "aws_iam_role" "check_foo_role" {
name="check-foo-assume-role"
assume_role_policy="assume_role_policy.json"
}
和assume_role_policy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Effect": "Allow",
"Sid": ""
}
]
}
和引用上述资源 iam 角色的策略,即像
resource "iam_role_policy" "check-foo-policy" {
name="check-foo-lambda-policy"
# referencing the iam role above
role="${aws_iam_role.check_foo_role.id}"
policy="check-foo-policy.json"
}
最后 json 指定策略,check-foo-policy.json
。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": ["*"]
},
{
"Effect": "Allow",
"Action": [
"abc:SomeAction",
"abc:AnotherAction",
],
"Resource": "some-arn-matching-the-actions"
}
请注意,您不能为与日志相关的操作指定资源限制。 abc:SomeAction
可能是 ssm:GetParameter
伴随的资源 arn 像 "arn:aws:ssm:us-east-1:${your-aws-account-id}:parameter/some/parameter/path/*
作为已接受答案的补充。通常人们希望 lambda 的 zip 文件也由 terraform 创建。为此,可以使用 archive_file data source:
data "archive_file" "lambda_zip" {
type = "zip"
source_dir = "src"
output_path = "check_foo.zip"
}
resource "aws_lambda_function" "check_foo" {
filename = "check_foo.zip"
function_name = "checkFoo"
role = "arn:aws:iam::424242:role/something"
handler = "index.handler"
}
# then the rest from the accepted answer to trigger this
如果代码处于版本控制之下,这将特别有用,因为这样您就可以将 check_foo.zip
添加到 .gitignore
并且 zip 文件和源代码之间永远不会出现不匹配它基于。
我想每五分钟 运行 一个 AWS lambda 函数。在 AWS 管理控制台中,这很容易设置,在 lambda 函数的 "Event Sources" 选项卡下,但如何使用 Terraform?
进行设置我尝试使用 an aws_lambda_event_source_mapping
resource, but it turns out that the API it uses 仅支持来自 Kinesis 和 DynamoDB 的事件。当我尝试将它与计划的事件源一起使用时,创建超时。
您可以使用 aws_cloudwatch_event_target
资源将计划的事件源(事件规则)绑定到您的 lambda 函数。您需要授予它调用您的 lambda 函数的权限;您可以为此使用 aws_lambda_permission
资源。
示例:
resource "aws_lambda_function" "check_foo" {
filename = "check_foo.zip"
function_name = "checkFoo"
role = "arn:aws:iam::424242:role/something"
handler = "index.handler"
}
resource "aws_cloudwatch_event_rule" "every_five_minutes" {
name = "every-five-minutes"
description = "Fires every five minutes"
schedule_expression = "rate(5 minutes)"
}
resource "aws_cloudwatch_event_target" "check_foo_every_five_minutes" {
rule = aws_cloudwatch_event_rule.every_five_minutes.name
target_id = "check_foo"
arn = aws_lambda_function.check_foo.arn
}
resource "aws_lambda_permission" "allow_cloudwatch_to_call_check_foo" {
statement_id = "AllowExecutionFromCloudWatch"
action = "lambda:InvokeFunction"
function_name = aws_lambda_function.check_foo.function_name
principal = "events.amazonaws.com"
source_arn = aws_cloudwatch_event_rule.every_five_minutes.arn
}
Verbjorns Ljosa 的回答仅包含 cloudwatch 调用 lambda 的权限。您是否指定了允许 lambda 执行其操作的适当策略和 iam 角色?
resource "aws_iam_role" "check_foo_role" {
name="check-foo-assume-role"
assume_role_policy="assume_role_policy.json"
}
和assume_role_policy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Effect": "Allow",
"Sid": ""
}
]
}
和引用上述资源 iam 角色的策略,即像
resource "iam_role_policy" "check-foo-policy" {
name="check-foo-lambda-policy"
# referencing the iam role above
role="${aws_iam_role.check_foo_role.id}"
policy="check-foo-policy.json"
}
最后 json 指定策略,check-foo-policy.json
。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": ["*"]
},
{
"Effect": "Allow",
"Action": [
"abc:SomeAction",
"abc:AnotherAction",
],
"Resource": "some-arn-matching-the-actions"
}
请注意,您不能为与日志相关的操作指定资源限制。 abc:SomeAction
可能是 ssm:GetParameter
伴随的资源 arn 像 "arn:aws:ssm:us-east-1:${your-aws-account-id}:parameter/some/parameter/path/*
作为已接受答案的补充。通常人们希望 lambda 的 zip 文件也由 terraform 创建。为此,可以使用 archive_file data source:
data "archive_file" "lambda_zip" {
type = "zip"
source_dir = "src"
output_path = "check_foo.zip"
}
resource "aws_lambda_function" "check_foo" {
filename = "check_foo.zip"
function_name = "checkFoo"
role = "arn:aws:iam::424242:role/something"
handler = "index.handler"
}
# then the rest from the accepted answer to trigger this
如果代码处于版本控制之下,这将特别有用,因为这样您就可以将 check_foo.zip
添加到 .gitignore
并且 zip 文件和源代码之间永远不会出现不匹配它基于。