Use terraform to set up a lambda function triggered by a scheduled event source
As an addition to the accepted answer. Often times one would want the zip-file for the lambda to be created by terraform as well. To do so one can use the archive_file data source:
data "archive_file" "lambda_zip" {
type = "zip"
source_dir = "src"
output_path = "check_foo.zip"
}
resource "aws_lambda_function" "check_foo" {
filename = "check_foo.zip"
function_name = "checkFoo"
role = "arn:aws:iam::424242:role/something"
handler = "index.handler"
}
# then the rest from the accepted answer to trigger this
That is particularly helpful if the code is under version control, because then you can add the check_foo.zip
to the .gitignore
and there can never be a missmatch between the zip file and the source code that it is based on.
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/*