Exécuter automatiquement une lambda de manière régulière
Tags: aws, devops, sre, tutorial
Published: 2023-05-01 14:02:00

Avoir un traîtement qui s'exécute de manière régulière se révèle très souvent être important pour faire de nombreuses petites tâches répétitives. Du coup, aujourd'hui on va voir comment faire pour exécuter une lambda de manière régulière!

---

## Vision globale

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

Comme vous pouvez le constater, c'est quelque chose de très simple, il ne suffit que **d'EventBridge** pour pouvoir exécuter ce dont on a besoin!

### AWS EventBridge

Rapidement, on va faire un point sur ce qu'est [**AWS EventBridge**](https://aws.amazon.com/eventbridge/?nc1=h_ls). 

> AWS EventBridge est une service d'AWS qui permet de faciliter les architectures évènementielles.  Il permet au travers de ses fonctionnalités de planifier l'exécution automatique de certaines tâches, ou d'en exécuter d'autre à chaque fois qu'un certain nombre de conditions sont réunies.

---

## Mise en place
### Lambda
Pour la lambda, on va utiliser le modèle "Hello World" en Python. Cet exemple est suffisant par rapport à nos besoins de test.

```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,
	}
```

Son fichier **Terraform** est aussi très simple et ressemble à ça
```
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 = ["*"]
	}
}
```

**Attention**, la défintion du `permissions_boundary` pour le role IAM n'a pas été mis et c'est la seule chose qui manque pour que vous puissiez l'utiliser à 100%.

Donc là on a ce qu'il faut pour pouvoir déployer une lambda qui va effectuer juste écrire des logs. Maintenant on va pouvoir passer à la définition de son déclancheur!

### EventBridge
La déclation de la partie EventBridge va se faire en 3 blocs  : 
- **aws_cloudwatch_event_rule** : Qui va définir par quel biais on a lancer une exécution *(Ici la définition d'un scheduler)*
- **aws_cloudwatch_event_target** : Qui va permettre de définir la cible de l'exécution évènementielle définie juste avant
- **aws_lambda_permission** : Pour permettre à EventBridge pour pouvoir exécuter la lambda

Le bloc Terraform ressemble à ça 
```
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"
}
```

Dans ce bloc il n'y a qu'une seule chose que vous aurez à toucher, c'est le champ `schedule_expression`.

En effet c'est ici que vous allez définir le cron **qui va définir quand est-ce que votre lambda doit être exécutée.** 

Dans l'exemple que vous avez ici, la lambda sera exécutée toutes les 10 minutes du lundi au vendredi. Si jamais vous voulez avoir plus d'informations sur comment construire ce cron, je vous invite à aller sur [cette documentation d'AWS](https://docs.aws.amazon.com/lambda/latest/dg/services-cloudwatchevents-expressions.html) qui fait le point sur la rédaction d'un cron.

---
## Exécution
Maintenant que vous avez tous les fichiers terraform en main, vous pouvez à présent les éxécuter et profiter de ce traitement automatisé!

---

J'espère que ça vous aidera! 🍺

---

<center><h3>Vous voulez me supporter?</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>