Execute a lambda every X minutes
Tags: aws, tutorial, devops, sre
Published: 2023-05-01 14:03:00

Having a treatment that is executed regularly can be really important for a lot of project to do a lot of little tasks. So we will see today how we can do it in AWS!

---

## Global vision

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xhs5xp22p4l0dpgugv0v.png)

As you can see, it's a really simple architecture to be able to do it. In fact, we only need **EventBridge** to do it.

### AWS EventBridge

Quick overview about  [**AWS EventBridge**](https://aws.amazon.com/eventbridge/?nc1=h_ls). 

> AWS EventBridge is an AWS service which facilitate event driven architectures. It allows with all its features to plan execution of tasks regularly, or if every time some specific actions happen.

---

## Set up
### Lambda
About the lambda code, we will use the Python "Hello World" template. This example is enough for our need in this example.

```python
import logging
import os
import boto3

logger = logging.getLogger()

logger.setLevel(logging.INFO)

def lambda_handler(event, context):
	logger.info(f'Hello World!')
	logger.info(f'## ENVIRONMENT VARIABLES: {os.environ}')
	logger.info(f'## EVENT: {event}')
	
	return {
		'statusCode': 200,
	}
```

Its Terraform file is simple too, and is like every other terraform file to deploy a lambda
```
data "archive_file" "lambda_zip" {
	type = "zip"
	source_file = "${path.module}/src/hello_world.py"
	output_file_mode = "0666"
	output_path = "${path.module}/bin/hello_world.py.zip"
}

resource "aws_lambda_function" "processing_lambda" {
	filename = data.archive_file.lambda_zip.output_path
	function_name = "hello_world"
	handler = "hello_world.lambda_handler"
	source_code_hash = data.archive_file.lambda_zip.output_base64sha256
	role = aws_iam_role.processing_lambda_role.arn
	runtime = "python3.9"
	timeout = 900
	memory_size = 10240
	tags = {
		 "service": "cron_lambda"
	}
}

resource "aws_iam_role" "processing_lambda_role" {
	name = hello_world_role
	path = "/service-role/"
	permissions_boundary = // To define correctly!
	assume_role_policy = data.aws_iam_policy_document.assume-role-policy_document.json
	
	inline_policy {
		name = "test_policy"
		policy = data.aws_iam_policy_document.test_policy_document.json
	}
}

data "aws_iam_policy_document" "assume-role-policy_document" {
	statement {
		actions = ["sts:AssumeRole"]
		
		principals {
			type = "Service"
			identifiers = ["lambda.amazonaws.com"]
		}
	}
}

data "aws_iam_policy_document" "test_policy_document" {
	statement {
		actions = [
			"logs:CreateLogGroup",
			"logs:CreateLogStream",
			"logs:PutLogEvents",
			"logs:AssociateKmsKey"
		]
		
		resources = ["*"]
	}
}
```

> **Warning** : `permissions_boundary`   field is not setup in this example, and it's the only thing  you need to setup to make it work.

Now that we have everything we need to deploy our lambda, we can go to the next step : write the terraform  file for the EventBridge stuff!

### EventBridge
Its declaration is in 3 blocks :
- **aws_cloudwatch_event_rule** : Which will define what are the conditions to trigger an event *(here it's our scheduler)*
- **aws_cloudwatch_event_target** : Which will define what will be execute when the event is triggered
- **aws_lambda_permission** : Which are some permissions to allow EventBridge to call a  lambda function.

The Terraform file looks like this :
```
resource "aws_cloudwatch_event_rule" "scheduler" {
	name = "scheduler_lambda_cron"
	description = "Schedule for Lambda Function"
	schedule_expression = "cron(0/10 * ? * MON-FRI *)"
}

resource "aws_cloudwatch_event_target" "schedule_lambda" {
	rule = aws_cloudwatch_event_rule.scheduler.name
	target_id = "processing_lambda"
	arn = aws_lambda_function.processing_lambda.arn
}

resource "aws_lambda_permission" "allow_events_bridge_to_run_lambda" {
	statement_id = "AllowExecutionFromCloudWatch"
	action = "lambda:InvokeFunction"
	function_name = aws_lambda_function.processing_lambda.function_name
	principal = "events.amazonaws.com"
}
```

In this part, there's only one thing to think about, and it's the `schedule_expression` field. It's here that you will define **when your lambda will be executed**.

In this example, the lambda function will be called every 10  minutes during weekdays.

If you want to have more informations about crons and how to update it, please check [this documentation from AWS](https://docs.aws.amazon.com/lambda/latest/dg/services-cloudwatchevents-expressions.html).

---
## Execution
Now that you have everything, you can deploy all the stuff and enjoy more automated treatments!

---

I  hope  it will help you! 🍺

---

<center><h3>You want to support me?</h3></center>
<a href="https://www.buymeacoffee.com/mxguilbert7" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/default-orange.png" alt="Buy Me A Coffee" height="41" width="174"></a>