Générer un reporting des mails Bounce et Complaint avec Amazon SES et Cloudwatch Logs Insights

Quelques définitions
Qu’est-ce qu’un Bounce ou un Complaint ?
- Bounce : Un bounce email est un email qui va nous être renvoyé et qui n’a pas pu être remis au destinataire. On a deux types de mail bounce :
- Soft Bounce : Une raison normalement non permanente fait en sorte que le mail n’a pas pu être remis. Par exemple, une adresse mail valide mais une boite aux lettres pleine ou bien un message trop gros qui ne respecte pas la limite imposée par le serveur mail.
- Hard Bounce : Dans ce cas, l’adresse mail peut ne pas exister du tout (que ce soit le user ou bien le domaine).
- Complaint : Globalement, cela veut dire que votre email a été marqué comme indésirable par son destinataire.
Contexte
L’idée était d’avoir une vue compléte et précise des mails Bounce et Complaint sur Amazon SES pour pouvoir intervenir rapidement dans le cas où le taux de ces types de mails envoyés par SES augmenterait dangeuresement pour arriver à la limite d’Amazon qui implique un blocage total de l’envoie de mail : FAQ SES.
Et oui, on ne pourra pas utiliser SES pour faire du SPAM :-)
Je voulais aussi une architecture simple à mettre en place.
Architecture
Nous avons là une architecture très simple. Amazon SES est configuré pour envoyer via un topic SNS les mails BOUNCE et COMPLAINT (il est aussi possible d’envoyer ceux en DELIVERED). Ensuite on setup une lambda qui est connectée au topic SNS et qui se chargera de log dans un groupe de log Cloudwatch.
Configuration d’Amazon SES
Tout est indiqué dans la documentation d’Amazon SES. Il suffit d’aller dans les paramétres de SES et d’éditer la partie Notification pour intereconnecter SES avec notre topic SNS.
Mise en place de SNS et Lambda
Ci-dessous le code python de notre Lambda :
import json
def lambda_handler(event, context):
message = event['Records'][0]['Sns']['Message']
print("From SNS: " + message)
return message
Code très simple. On récupére le message renvoyé par SNS et on l’affiche. Cela aura pour effet de le logger dans notre groupe de Logs Cloudwatch.
On doit aussi créer un rôle IAM que notre Lambda pourra assumer :
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:Assumerole",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Effect": "Allow",
"Sid": ""
}
]
}
Il faut ensuite créer une policy pour notre rôle qui permettra à la lambda de logger dans Cloudwatch :
{
"Version":"2012-10-17",
"Statement":[
{
"Effect":"Allow",
"Action":[
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource":[
"arn:aws:logs:*:*:*"
]
}
]
}
Et enfin, il faut ajouter une permission Lambda pour qu’elle puisse être invoquée par notre topic SNS :
{
"Version": "2012-10-17",
"Id": "default",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "sns.amazonaws.com"
},
"Action": "lambda:InvokeFunction",
"Resource": "arn:aws:lambda:eu-west-1:${account_id}:function:${lambda_name}",
"Condition": {
"ArnLike": {
"AWS:SourceArn": "arn:aws:sns:eu-west-1:${account_id}:${sns_topic_name}"
}
}
}
]
}
Bien entendu, il faudra remplacer les variables par vos valeurs…
Configuration de Cloudwatch Logs/Insights
Il suffit d’aller dans la partie Insights de Cloudwatch et de créer des requêtes (Query).
Requête pour filtrer les logs Bounce
fields @timestamp, notificationType, mail.sourceIp as sourceIp, mail.source as Sender, mail.destination.0 as Recepient1, mail.destination.1 as Recepient2, mail.commonHeaders.subject as Subject
| filter notificationType = "Bounce"
| sort @timestamp desc
Requête pour filtrer les logs Complaint
fields @timestamp, notificationType, mail.sourceIp as sourceIp, mail.source as Sender, mail.destination.0 as Recepient1, mail.destination.1 as Recepient2, mail.commonHeaders.subject as Subject
| filter notificationType = "Complaint"
| sort @timestamp desc
Résultat final
Cela donne un résultat semblable à celui ci-dessous que j’ai anonymisé.
Conclusion
Dans cet article nous avons pu voir comment il était simple d’avoir un reporting SES avec Cloudwatch Logs Insights. On peut imaginer des architectures beaucoup plus complexes avec une gestion des mails dans une base RDS, etc etc… Mais une fois de plus, il est important de proposer l’architecture la plus adéquat avec le besoin et le budget. En soit une définition simple d’un architecte cloud.