Cloudwatch 事件没有触发我的 lambda 函数,即使它是一个目标
Cloudwatch event is not triggering my lambda function, even though it's a target
我有一个 lambda 函数,它接受一个数据集名称,并专门为该数据集创建一个新的 lambda。这是设置它的代码:
lambda_response = lambda_client.create_function(
FunctionName=job_name,
Runtime='python3.6',
Role=role_name,
Handler='streaming_data_lambda.lambda_handler',
Code={
'S3Bucket': code_bucket,
'S3Key': 'streaming_data_lambda.py.zip'
},
Timeout=30,
)
这似乎正确地创建了一个 lambda,并且在我手动启动它时有效。我希望每小时创建一次 lambda 运行,因此原始 lambda 脚本创建以下规则和目标:
rule_response = event_client.put_rule(
Name=rule_name,
ScheduleExpression=schedule_expression
)
event_client.put_targets(
Rule=rule_name,
Targets=[
{
'Id': lambda_response['FunctionName'],
'Arn': lambda_response['FunctionArn'],
'Input': json.dumps(input_string)
}
]
)
其中 input_string 类似于 {"datasetName": "name"}。我可以在 CloudWatch 规则 UI 中看到规则,并且可以看到它链接到正确的 lambda 并且存在输入文本。它也每小时正确触发一次,但无法调用 lambda 函数。如果我查看 UI 中的 lambda 并将我创建的 CloudWatch 事件规则添加为那里的 Designer 部分中的触发器,那么它会正确地启动 lambda,但是有什么方法可以在 Python 所以我不必在 UI?
中执行最后一步
您可能需要添加
event_client.enable_rule(Name=rule_name)
之后put_rule
在这一点上,UI可能添加了一些额外的配置
event_client.put_rule(
Name=rule_name,
ScheduleExpression=schedule_expression)
尝试在该规则启用并工作后使用 "DescribeRule",然后在 python
中复制任何缺失的字段(如 RoleArn )
对于将来可能正在寻找此问题答案的任何人 - 您需要为 cloudwatch 事件添加权限以调用您的 lambda 函数,如下所示:
lambda_client.add_permission(
FunctionName=lambda_response['FunctionName'],
StatementId=some_random_number,
Action='lambda:InvokeFunction',
Principal='events.amazonaws.com',
SourceArn=rule_response['RuleArn']
)
@meowseph_furbalin 提到的答案会起作用,但这个答案的问题是对于每个规则,它都会向 lambda 添加新的资源策略。 AWS 将资源策略的最大大小限制在 2KB 左右,因此在达到该限制后,目标将不会被触发。
解决此问题的一种方法是向 lambda 添加通配符匹配,以便它可以匹配单个资源策略中的每个规则。
aws lambda add-permission --function-name lambda_name\
--action 'lambda:InvokeFunction' --principal events.amazonaws.com \
--statement-id '1' \
--source-arn arn:aws:events:us-west-2:356280712205:rule/*
添加此命令后,您无需向 lambda 动态添加权限,并且 lambda 将接受具有单一资源策略的所有 cloudwatch 规则。
- 请记住,在创建 cloudwatch 规则时,您必须将所有规则的 SID 保持为“1”。如果要更改 SID,请添加与该 SID 对应的另一条规则。
我有一个 lambda 函数,它接受一个数据集名称,并专门为该数据集创建一个新的 lambda。这是设置它的代码:
lambda_response = lambda_client.create_function(
FunctionName=job_name,
Runtime='python3.6',
Role=role_name,
Handler='streaming_data_lambda.lambda_handler',
Code={
'S3Bucket': code_bucket,
'S3Key': 'streaming_data_lambda.py.zip'
},
Timeout=30,
)
这似乎正确地创建了一个 lambda,并且在我手动启动它时有效。我希望每小时创建一次 lambda 运行,因此原始 lambda 脚本创建以下规则和目标:
rule_response = event_client.put_rule(
Name=rule_name,
ScheduleExpression=schedule_expression
)
event_client.put_targets(
Rule=rule_name,
Targets=[
{
'Id': lambda_response['FunctionName'],
'Arn': lambda_response['FunctionArn'],
'Input': json.dumps(input_string)
}
]
)
其中 input_string 类似于 {"datasetName": "name"}。我可以在 CloudWatch 规则 UI 中看到规则,并且可以看到它链接到正确的 lambda 并且存在输入文本。它也每小时正确触发一次,但无法调用 lambda 函数。如果我查看 UI 中的 lambda 并将我创建的 CloudWatch 事件规则添加为那里的 Designer 部分中的触发器,那么它会正确地启动 lambda,但是有什么方法可以在 Python 所以我不必在 UI?
中执行最后一步您可能需要添加
event_client.enable_rule(Name=rule_name)
之后put_rule
在这一点上,UI可能添加了一些额外的配置
event_client.put_rule(
Name=rule_name,
ScheduleExpression=schedule_expression)
尝试在该规则启用并工作后使用 "DescribeRule",然后在 python
中复制任何缺失的字段(如 RoleArn )对于将来可能正在寻找此问题答案的任何人 - 您需要为 cloudwatch 事件添加权限以调用您的 lambda 函数,如下所示:
lambda_client.add_permission(
FunctionName=lambda_response['FunctionName'],
StatementId=some_random_number,
Action='lambda:InvokeFunction',
Principal='events.amazonaws.com',
SourceArn=rule_response['RuleArn']
)
@meowseph_furbalin 提到的答案会起作用,但这个答案的问题是对于每个规则,它都会向 lambda 添加新的资源策略。 AWS 将资源策略的最大大小限制在 2KB 左右,因此在达到该限制后,目标将不会被触发。 解决此问题的一种方法是向 lambda 添加通配符匹配,以便它可以匹配单个资源策略中的每个规则。
aws lambda add-permission --function-name lambda_name\
--action 'lambda:InvokeFunction' --principal events.amazonaws.com \
--statement-id '1' \
--source-arn arn:aws:events:us-west-2:356280712205:rule/*
添加此命令后,您无需向 lambda 动态添加权限,并且 lambda 将接受具有单一资源策略的所有 cloudwatch 规则。
- 请记住,在创建 cloudwatch 规则时,您必须将所有规则的 SID 保持为“1”。如果要更改 SID,请添加与该 SID 对应的另一条规则。