I would like to run an AWS lambda function every five minutes. In the AWS Management Console this is easy to set up, under the lambda function's "Event Sources" tab, but how do I set it up with Terraform?
I tried to use an aws_lambda_event_source_mapping
resource, but it turns out that the API it uses only supports events from Kinesis and DynamoDB. When I try to use it with a scheduled event source, creation times out.
Create a file named main.tf inside the ~/terraform-lambda-demo directory and copy/paste the below content. The below file creates the below components: Creates IAM role and IAM policy that will be assumed by AWS Lambda to invoke a function. Creates the AWS Lambda function.
You can use an aws_cloudwatch_event_target
resource to tie the scheduled event source (event rule) to your lambda function. You need to grant it permission to invoke your lambda function; you can use an aws_lambda_permission
resource for this.
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}" }
Verbjorns Ljosa's answer only includes permissions for cloudwatch to invoke the lambda. Have you specified the proper policy and iam role that allows the lambda to perform its actions?
resource "aws_iam_role" "check_foo_role" { name="check-foo-assume-role" assume_role_policy="assume_role_policy.json" }
with assume_role_policy.json
{ "Version": "2012-10-17", "Statement": [ { "Action": "sts:AssumeRole", "Principal": { "Service": "lambda.amazonaws.com" }, "Effect": "Allow", "Sid": "" } ] }
and a policy referencing the above resource iam role I.e. something like
resource "iam_role_policy" "check-foo-policy" { name="check-foo-lambda-policy" # referencing the iam role above role="${aws_iam_role.check_foo_role.id}" policy="check-foo-policy.json" }
and finally the json specifying the policy, check-foo-policy.json
.
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents" ], "Resource": ["*"] }, { "Effect": "Allow", "Action": [ "abc:SomeAction", "abc:AnotherAction", ], "Resource": "some-arn-matching-the-actions" }
Do note that you cannot specify a Resource restriction for the logs-related actions. abc:SomeAction
might be ssm:GetParameter
with an accompanying resource arn like "arn:aws:ssm:us-east-1:${your-aws-account-id}:parameter/some/parameter/path/*
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With