39

I already have my lambda / roles defined in cloudformation and would love to also use it to add a scheduled eventsources ... are there any docs or examples around ?

7 Answers 7

43

Use Aws::Event::Rule with a ScheduleExpression and a AWS::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"
      ]
    }
  }
}
Sign up to request clarification or add additional context in comments.

6 Comments

According to the docs, ScheduleExpression needs to be plural minutes not minute. docs.aws.amazon.com/AmazonCloudWatch/latest/DeveloperGuide/…
@timmah.faase Not true? "Valid values: minute | minutes | hour | hours | day | days"
You're allowed singular on "1", e.g. "1 minute", but must use plural otherwise, e.g. "10 minutes". Grammar is enforced!
I wish I could upvote this a bunch of times. I'm certain you just saved me hours of my life.
How can we pass custom input to lambda function through event rule?
|
11

I solved same problem.

"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"] }
  }
}

2 Comments

In LambdaInvokePermission the SourceAccount property stopped it running for me
same as @jhanson, I had to remove the SourceArn line in LambdaInvokePermission
11

The YAML Version

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"

Comments

9

Unfortunately, configuring scheduled event sources for lambda functions is currently not supported by CloudFormation. You will need to deploy your lambda using CloudFormation and then manually configure your scheduled events.

CloudFormation does support an AWS::Lambda::EventSourceMapping resource type. However, this resource is limited configuring Kinesis or DynamoDB streams, so this is likely not helpful to you.

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


**Update - as of April 2016, this is now supported using CloudWatch Events - https://aws.amazon.com/about-aws/whats-new/2016/04/amazon-cloudwatch-events-now-supported-in-aws-cloudformation-templates/

Comments

4

As of this week (18 April 2016) it is now possible to add a scheduled CloudWatch event rule that will trigger your Lambda function.

The AWS::Event::Rule has a ScheduleExpression field for the cron-style schedule and a Targets array which can accept a Lambda function ARN.

Comments

1

AWS supports periodic run through sourcedetails.

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

Comments

1

If you use function name as

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

and you not specify the function then it'll throw you "Template is not valid: Template error: instance of Fn::GetAtt references undefined resource TagWatcherFunction"

So instead of function name you can directly specify the "lambda ARN". you can see example below

"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"
      ]
    }
  }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.