Lambda 的 AWS 计划事件规则在 CloudFormation 中不起作用

AWS Scheduled Event Rule for Lambda doesn't work in CloudFormation

无法使用 CloudFormation(实际上,使用 Python 的对流层)将 AWS Lambda 配置为由规则-> 触发器触发的计划事件源。这已经花费了我几天的时间,如有任何帮助,我们将不胜感激。

这是相关的 CF JSON 片段 -

        "DataloaderRetrier": {
        "Properties": {
            "Code": {
                "S3Bucket": "mycompanylabs-config",
                "S3Key": "v3/mycompany-component-loader-lambda-0.5.jar"
            },
            "FunctionName": "DataloaderRetriervitest27",
            "Handler": "mycompany.ScheduledEventHandler::handleRequest",
            "MemorySize": 320,
            "Role": "arn:aws:iam::166662328783:role/kinesis-lambda-role",
            "Runtime": "java8",
            "VpcConfig": {
                "SecurityGroupIds": [
                    "sg-2f1f6047"
                ],
                "SubnetIds": [
                    "subnet-ec3c1435"
                ]
            }
        },
        "Type": "AWS::Lambda::Function"
    },
    "DataloaderRetrierEventTriggerPermission": {
        "Properties": {
            "Action": "lambda:InvokeFunction",
            "FunctionName": {
                "Fn::GetAtt": [
                    "DataloaderRetrier",
                    "Arn"
                ]
            },
            "Principal": "events.amazonaws.com",
            "SourceAccount": {
                "Ref": "AWS::AccountId"
            },
            "SourceArn": {
                "Fn::GetAtt": [
                    "DataloaderRetrierEventTriggerRule",
                    "Arn"
                ]
            }
        },
        "Type": "AWS::Lambda::Permission"
    },
    "DataloaderRetrierEventTriggerRule": {
        "DependsOn": "DataloaderRetrier",
        "Properties": {
            "Description": "Reminding the lambda to read from the retry SQS",
            "Name": "DataloaderRetrierEventTriggerRulevitest27",
            "ScheduleExpression": "rate(1 minute)",
            "State": "ENABLED",
            "Targets": [
                {
                    "Arn": {
                        "Fn::GetAtt": [
                            "DataloaderRetrier",
                            "Arn"
                        ]
                    },
                    "Id": "DataloaderRetrierEventTriggerTargetvitest27",
                    "Input": "{\"Hey\":\"WAKE UP!\"}"
                }
            ]
        },
        "Type": "AWS::Events::Rule"
    }

AWS Lambda 函数显示调用次数为零,事件 -> 规则指标显示正确的调用次数,但它们都失败了。 Lambda 在触发器部分显示触发器,规则在其触发器部分显示 lambda。他们 link 很好。

但是,如果我进去并在 Web 控制台的规则下手动创建 相同的触发器 ,它会愉快地开始向 Lambda 发送事件。

PS - 这是对流层代码:

# DATALOADER RETRIER LAMBDA
dataloader_retrier = t.add_resource(awslambda.Function(
    "DataloaderRetrier",
    Code=awslambda.Code(
        "DataloaderRetrierCode",
        S3Bucket='mycompanylabs-config',
        S3Key='v3/mycompany-snowplow-loader-lambda-0.5.jar'
    ),
    FunctionName=suffix("DataloaderRetrier"),
    Handler="mycompany.ScheduledEventHandler::handleRequest",
    MemorySize="320",
    Role="arn:aws:iam::166662328783:role/kinesis-lambda-role",
    Runtime="java8",
    VpcConfig=lambda_vpc_config
))

dataloader_retrier_scheduled_rule = t.add_resource(events.Rule(
    "DataloaderRetrierEventTriggerRule",
    Name=suffix("DataloaderRetrierEventTriggerRule"),
    Description="Reminding the lambda to read from the retry SQS",
    Targets=[events.Target(
        Id=suffix("DataloaderRetrierEventTriggerTarget"),
        Arn=tr.GetAtt("DataloaderRetrier", "Arn"),
        Input='{"Hey":"WAKE UP!"}'
    )],
    State='ENABLED',
    ScheduleExpression="rate(1 minute)",
    DependsOn="DataloaderRetrier"
)),

t.add_resource(awslambda.Permission(
    "DataloaderRetrierEventTriggerPermission",
    Action="lambda:InvokeFunction",
    FunctionName=tr.GetAtt("DataloaderRetrier", "Arn"),
    Principal="events.amazonaws.com",
    SourceAccount=tr.Ref("AWS::AccountId"),
    SourceArn=tr.GetAtt("DataloaderRetrierEventTriggerRule", "Arn")
))

您需要删除 SourceAccount parameter from your AWS::Lambda::Permission 资源。

AddPermission API documentation, the SourceAccount 参数所述,将允许的调用 'source' 限制为指定的 AWS 账户 ID,例如在指定 S3 存储桶或 CloudWatch Logs 通知时。

但是(在这一点上文档应该更清楚),在 CloudWatch Events Schedule Expression 的情况下,事件的 sourceaws.events,而不是你自己的AWS Account ID,这就是为什么添加这个参数导致事件无法触发Lambda函数的原因。