Terraform: Support Scheduled Event event source for AWS Lambda

Created on 19 Dec 2015  ยท  10Comments  ยท  Source: hashicorp/terraform

It seems the aws_lambda_event_source_mapping resource only currently supports events from Kinesis and DynamoDB. Lambda can be a nice replacement for cron when using the Scheduled Event source, so it would be nice if Terraform could support it.

Most helpful comment

@abevoelker: I believe you can do what you want (fire lambda functions from cron) with aws_cloudwatch_event_rule and aws_cloudwatch_event_target. Example:

resource "aws_lambda_function" "check_foo" {
    filename = "check_foo.zip"
    function_name = "checkFoo"
    role = "arn:aws:iam::424242:role/something"
    handler = "index.handler"
}

resource "aws_cloudwatch_event_rule" "every_five_minutes" {
    name = "every-five-minutes"
    description = "Fires every five minutes"
    schedule_expression = "rate(5 minutes)"
}

resource "aws_cloudwatch_event_target" "check_foo_every_five_minutes" {
    rule = "${aws_cloudwatch_event_rule.every_five_minutes.name}"
    target_id = "check_foo"
    arn = "${aws_lambda_function.check_foo.arn}"
}

resource "aws_lambda_permission" "allow_cloudwatch_to_call_check_foo" {
    statement_id = "AllowExecutionFromCloudWatch"
    action = "lambda:InvokeFunction"
    function_name = "${aws_lambda_function.check_foo.function_name}"
    principal = "events.amazonaws.com"
    source_arn = "${aws_cloudwatch_event_rule.every_five_minutes.arn}"
}

Perhaps this should be mentioned in the documentation for the aws_lambda_event_source_mapping resource.

All 10 comments

Hey @abevoelker, the resource was implemented off of the CreateEventSourceMapping call, which has the following parameters. In there, it seems that Kinesis and Dynamo are the only options available as the sources.

Also, it looks like this is a console only feature:

This functionality is only available when you create a Lambda function using the
AWS Lambda console. The console provides the Scheduled Event as an event
source. At the time of creating a Lambda function, you choose this event source
and specify a time interval.

If you know of a way to get this thru the SDK, let me know!

Gah, sorry, I didn't realize AWS constrained things in such a way. I'll close the issue until things change. Thanks for looking into it!

No problem! Hope the resource is of use to you guys otherwise! If you see the functionality get added @ me and I'll try to get it in the resource.

@abevoelker: I believe you can do what you want (fire lambda functions from cron) with aws_cloudwatch_event_rule and aws_cloudwatch_event_target. Example:

resource "aws_lambda_function" "check_foo" {
    filename = "check_foo.zip"
    function_name = "checkFoo"
    role = "arn:aws:iam::424242:role/something"
    handler = "index.handler"
}

resource "aws_cloudwatch_event_rule" "every_five_minutes" {
    name = "every-five-minutes"
    description = "Fires every five minutes"
    schedule_expression = "rate(5 minutes)"
}

resource "aws_cloudwatch_event_target" "check_foo_every_five_minutes" {
    rule = "${aws_cloudwatch_event_rule.every_five_minutes.name}"
    target_id = "check_foo"
    arn = "${aws_lambda_function.check_foo.arn}"
}

resource "aws_lambda_permission" "allow_cloudwatch_to_call_check_foo" {
    statement_id = "AllowExecutionFromCloudWatch"
    action = "lambda:InvokeFunction"
    function_name = "${aws_lambda_function.check_foo.function_name}"
    principal = "events.amazonaws.com"
    source_arn = "${aws_cloudwatch_event_rule.every_five_minutes.arn}"
}

Perhaps this should be mentioned in the documentation for the aws_lambda_event_source_mapping resource.

@ljosa Thank you very much, that looks perfect! :metal:

I try to create two Lambda functions, run it by the scheduler.

However, I ran into a problem.

Here is my code:

resource "aws_lambda_function" "EBSToSnapshotBackup" {
    filename = "ebs_to_snapshot_backup.py.zip"
    function_name = "ebs_to_snapshot_backup"
    description = "Set instance tags: backup=true, Retention=days"
    runtime = "python2.7"
    role = "${aws_iam_role.ebs-backup-worker.arn}"
    handler = "ebs_to_snapshot_backup.lambda_handler"
}

resource "aws_lambda_function" "EBSSnapshotRotation" {
    filename = "ebs-snapshot-janitor.py.zip"
    function_name = "ebs-snapshot-janitor"
    runtime = "python2.7"
    role = "${aws_iam_role.ebs-backup-worker.arn}"
    handler = "ebs-snapshot-janitor.lambda_handler"
}

resource "aws_lambda_permission" "allow_cloudwatch_to_call_EBSToSnapshotBackup" {
    statement_id = "AllowExecutionFromCloudWatch"
    action = "lambda:InvokeFunction"
    function_name = "${aws_lambda_function.EBSToSnapshotBackup.function_name}"
    principal = "events.amazonaws.com"
    source_arn = "${aws_cloudwatch_event_rule.every_day.arn}"
}

resource "aws_lambda_permission" "allow_cloudwatch_to_call_EBSSnapshotRotation" {
    statement_id = "AllowExecutionFromCloudWatch"
    action = "lambda:InvokeFunction"
    function_name = "${aws_lambda_function.EBSSnapshotRotation.function_name}"
    principal = "events.amazonaws.com"
    source_arn = "${aws_cloudwatch_event_rule.every_day.arn}"
}

resource "aws_cloudwatch_event_rule" "every_day" {
    name = "every_day"
    description = "Fires every day"
    schedule_expression = "rate(1 day)"
}

resource "aws_cloudwatch_event_target" "EBSToSnapshotBackup_every_day" {
    rule = "${aws_cloudwatch_event_rule.every_day.name}"
    target_id = "ebs_to_snapshot_backup"
    arn = "${aws_lambda_function.EBSToSnapshotBackup.arn}"
}

resource "aws_cloudwatch_event_target" "EBSSnapshotRotation_every_day" {
    rule = "${aws_cloudwatch_event_rule.every_day.name}"
    target_id = "ebs-snapshot-janitor"
    arn = "${aws_lambda_function.EBSSnapshotRotation.arn}"
}

Terraform is able to successfully create the necessary infrastructure.

But the connection between Cloudwatch scheduled event and Lambda functions not being created correctly.

And therefore lambda functions are not triggered by the event scheduler.

2016-03-24 8 33 00

To successfully run the scheduler, in the tab 'Event sources' in the Lambda function must be an event every_day but it is not added.

2016-03-24 8 33 22

@dmitryint I think this can be caused by missing/incorrect aws_lambda_permission which you seem to have in place, but generally closed issue is not the best place to ask about such things, especially if this issue isn't discussing a bug that could be reopened, but an initial implementation/feature request.

Open a new issue and we can have a look at it more deeply - copy-pasting you existing comment in it's raw Markdown format is :ok_hand: .

Thanks!

@dmitryint I had a similar issue, I got it working when I changed statement_id

resource "aws_lambda_permission" "allow_cloudwatch_to_call_EBSToSnapshotBackup" {
    statement_id = "AllowExecutionFromCloudWatch"

to something unique like
AllowExecutionFromCloudWatch-call_EBSToSnapshotBackup

and for the other one something like

resource "aws_lambda_permission" "allow_cloudwatch_to_call_EBSSnapshotRotation" {
    statement_id = "AllowExecutionFromCloudWatch"

AllowExecutionFromCloudWatch-call_EBSSnapshotRotation

Note I had to remove everything around the lambda and recreate it though.

@rasmuskr
It's worked! thanx!

I'm going to lock this issue because it has been closed for _30 days_ โณ. This helps our maintainers find and focus on the active issues.

If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

Was this page helpful?
0 / 5 - 0 ratings