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
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"
]
}
}
}
-
1According to the docs, ScheduleExpression needs to be plural minutes not minute. docs.aws.amazon.com/AmazonCloudWatch/latest/DeveloperGuide/… Apr 24, 2016 at 0:43
-
@timmah.faase Not true? "Valid values: minute | minutes | hour | hours | day | days" Dec 20, 2016 at 15:06
-
12You're allowed singular on "1", e.g. "1 minute", but must use plural otherwise, e.g. "10 minutes". Grammar is enforced! Dec 31, 2016 at 21:09
-
1I wish I could upvote this a bunch of times. I'm certain you just saved me hours of my life. Jun 5, 2018 at 20:10
-
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"] }
}
}
-
In LambdaInvokePermission the SourceAccount property stopped it running for me– jhansonJan 26, 2017 at 15:33
-
same as @jhanson, I had to remove the SourceArn line in LambdaInvokePermission Jul 23, 2020 at 12:38
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"
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.
**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/
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.
AWS supports periodic run through sourcedetails.
EventSource: "aws.config"
MaximumExecutionFrequency: Twelve_Hours
MessageType: "ScheduledNotification"
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"
]
}
}
}