适用于 Lambda 的 AWS 计划事件规则在 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。他们连接得很好。

但是,如果我进入并在 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")
))
您需要

AWS::Lambda::Permission资源中删除SourceAccount参数。

AddPermission API 文档中所述,SourceAccount 参数将允许调用的"源"限制为指定的 AWS 账户 ID,例如在指定 S3 存储桶或 CloudWatch 日志通知时。

但是(在这一点上,文档可能应该更清楚),在 CloudWatch 事件计划表达式的情况下,事件的sourceaws.events ,而不是您自己的 AWS 账户 ID,这就是添加此参数会导致事件无法触发 Lambda 函数的原因。

最新更新