通过 cloudformation 的 AWS Lambda 计划事件源

Posted

技术标签:

【中文标题】通过 cloudformation 的 AWS Lambda 计划事件源【英文标题】:AWS Lambda scheduled event source via cloudformation 【发布时间】:2016-03-25 12:57:39 【问题描述】:

我已经在 cloudformation 中定义了我的 lambda / 角色,并且很想用它来添加计划的事件源...周围有任何文档或示例吗?

【问题讨论】:

【参考方案1】:

如果你使用函数名作为

"FunctionName": 
      "Fn::GetAtt": [
        "TagWatcherFunction",
        "Arn"
      ]
    

如果你没有指定函数,那么它会抛出你 “模板无效:模板错误:Fn::GetAtt 实例引用未定义资源 TagWatcherFunction”

因此,您可以直接指定“lambda ARN”,而不是函数名称。 你可以看下面的例子

"TagWatcherRule": 
  "Type": "AWS::Events::Rule",
  "Properties": 
    "ScheduleExpression": "rate(10 minutes)",
    "Targets": [
      
        "Id": "TagWatcherScheduler",
        "Arn": 
          "Fn::GetAtt": [
            "TagWatcherFunction",
            "Arn"
          ]
        
      
    ]
  
,
// role may call the lambda
"InvokeLambdaPermission": 
  "Type": "AWS::Lambda::Permission",
  "Properties": 
    "FunctionName": "arn:aws:lambda:<region>:<awsid>:function:<lambd name>",
    "Action": "lambda:InvokeFunction",
    "Principal": "events.amazonaws.com",
    "SourceArn": 
      "Fn::GetAtt": [
        "TagWatcherRule",
        "Arn"
      ]
    
  

【讨论】:

【参考方案2】:

YAML 版本

ScheduledRule: 
  Type: AWS::Events::Rule
  Properties: 
    Description: "ScheduledRule"
    ScheduleExpression: "rate(10 minutes)"
    State: "ENABLED"
    Targets: 
      - 
        Arn: 
          Fn::GetAtt: 
            - "LambdaFunction"
            - "Arn"
        Id: "TargetFunctionV1"
PermissionForEventsToInvokeLambda: 
  Type: AWS::Lambda::Permission
  Properties: 
    FunctionName: 
      Ref: "LambdaFunction"
    Action: "lambda:InvokeFunction"
    Principal: "events.amazonaws.com"
    SourceArn: 
      Fn::GetAtt: 
        - "ScheduledRule"
        - "Arn"

【讨论】:

【参考方案3】:

AWS supports periodic run through sourcedetails.

 EventSource: "aws.config"
 MaximumExecutionFrequency: Twelve_Hours
 MessageType: "ScheduledNotification"

【讨论】:

【参考方案4】:

将Aws::Event::Rule 与ScheduleExpressionAWS::Lambda::Permission 一起使用

// rule to periodically call the lambda
"TagWatcherRule": 
  "Type": "AWS::Events::Rule",
  "Properties": 
    "ScheduleExpression": "rate(10 minutes)",
    "Targets": [
      
        "Id": "TagWatcherScheduler",
        "Arn": 
          "Fn::GetAtt": [
            "TagWatcherFunction",
            "Arn"
          ]
        
      
    ]
  
,
// role may call the lambda
"InvokeLambdaPermission": 
  "Type": "AWS::Lambda::Permission",
  "Properties": 
    "FunctionName": 
      "Fn::GetAtt": [
        "TagWatcherFunction",
        "Arn"
      ]
    ,
    "Action": "lambda:InvokeFunction",
    "Principal": "events.amazonaws.com",
    "SourceArn": 
      "Fn::GetAtt": [
        "TagWatcherRule",
        "Arn"
      ]
    
  

【讨论】:

根据文档,ScheduleExpression 需要是复数分钟而不是分钟。 docs.aws.amazon.com/AmazonCloudWatch/latest/DeveloperGuide/… @timmah.faase 不正确? "有效值:分钟 | 分钟 | 小时 | 小时 | 天 | 天" 您可以在“1”上使用单数,例如“1 分钟”,但必须使用复数,否则,例如“10分钟”。语法被强制执行! 我希望我能多次投票。我敢肯定,你刚刚救了我几个小时。 我们如何通过事件规则将自定义输入传递给 lambda 函数?【参考方案5】:

我解决了同样的问题。

"RoleForLambdaStopEC2Instances" : 
  "Type": "AWS::IAM::Role",
  "Properties": 
    "AssumeRolePolicyDocument": 
      "Version": "2012-10-17",
      "Statement": [
        
          "Sid": "",
          "Effect": "Allow",
          "Principal": 
            "Service": "lambda.amazonaws.com"
          ,
          "Action": "sts:AssumeRole"
        
      ]
    ,
    "Policies": [
      
        "PolicyName": "LambdaStopEC2InstancesPolicy",
        "PolicyDocument": 
          "Version": "2012-10-17",
          "Statement": [
            
              "Effect": "Allow",
              "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents",
                "ec2:StopInstances"
              ],
              "Resource": [
                "arn:aws:logs:*:*:*",
                "arn:aws:ec2:*"
              ]
            
          ]
        
      
    ],
    "Path": "/"
  
,
"LambdaStopEC2Instances": 
  "Type": "AWS::Lambda::Function",
  "Properties": 
    "Code": 
      "S3Bucket": "XXXXXXXXXXXXXXXXX",
      "S3Key": "XXXXXXXXXXXXXXXXXX"
    ,
    "Handler": "stopEC2Instances.handler",
    "Role":  "Fn::GetAtt" : ["RoleForLambdaStopEC2Instances", "Arn"] ,
    "Runtime": "nodejs4.3",
    "Timeout": "5"
  
,
"StopEC2InstancesRule": 
  "Type" : "AWS::Events::Rule",
  "Properties" : 
    "Name" : "StopEC2Instances",
    "ScheduleExpression" : "cron(0 13 ? * MON-FRI *)",
    "State": "ENABLED",
    "Targets": [
      "Arn":  "Fn::GetAtt": ["LambdaStopEC2Instances", "Arn"] ,
      "Id": "stopEC2Instances"
    ]
  
,
"LambdaInvokePermission": 
  "Type": "AWS::Lambda::Permission",
  "Properties": 
    "FunctionName" :  "Fn::GetAtt" : ["LambdaStopEC2Instances", "Arn"] ,
    "Action": "lambda:InvokeFunction",
    "Principal": "events.amazonaws.com",
    "SourceAccount":  "Ref" : "AWS::AccountId" ,
    "SourceArn":  "Fn::GetAtt": ["StopEC2InstancesRule","Arn"] 
  

【讨论】:

在 LambdaInvokePermission 中,SourceAccount 属性停止了它为我运行 与@jhanson 相同,我必须删除 LambdaInvokePermission 中的 SourceArn 行【参考方案6】:

很遗憾,CloudFormation 目前不支持为 lambda 函数配置计划事件源。您将需要使用 CloudFormation 部署您的 lambda,然后手动配置您的计划事件。

CloudFormation 确实支持 AWS::Lambda::EventSourceMapping 资源类型。但是,此资源仅限于配置 Kinesis 或 DynamoDB 流,因此可能对您没有帮助。

http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-eventsourcemapping.html


**更新 - 自 2016 年 4 月起,现在支持使用 CloudWatch Events - https://aws.amazon.com/about-aws/whats-new/2016/04/amazon-cloudwatch-events-now-supported-in-aws-cloudformation-templates/

【讨论】:

【参考方案7】:

从本周(2016 年 4 月 18 日)开始,现在可以添加触发您的 Lambda 函数的计划 CloudWatch 事件规则。

AWS::Event::Rule 有一个用于 cron 样式计划的 ScheduleExpression 字段和一个可以接受 Lambda 函数 ARN 的 Targets 数组。

【讨论】:

以上是关于通过 cloudformation 的 AWS Lambda 计划事件源的主要内容,如果未能解决你的问题,请参考以下文章

我应该如何通过 cloudformation 部署我的 aws 状态机?

通过 CloudFormation 部署 AWS UserPool 并更新属性

通过 cloudformation 使用 aws `cdk synth` 输出

AWS Cognito 用户池通过 cloudformation 文件

通过 cloudformation 的 AWS Lambda 计划事件源

AWS::CloudFormation::Init 它是如何工作的?