Pourquoi Amazon SNS n'appelle-t-il pas ma fonction Lambda lorsqu'elle est déclenchée par une alarme CloudWatch ?

Date de la dernière mise à jour : 24/06/2021

Je souhaite qu'Amazon Simple Notification Service (Amazon SNS) appelle ma fonction AWS Lambda lorsqu'elle est déclenchée par une alarme Amazon CloudWatch.

Brève description

Les scénarios suivants vous empêchent d'appeler votre fonction Lambda :

  • La stratégie de ressources de votre fonction Lambda n'a pas autorisé l'accès à la fonction à partir de la rubrique SNS. Pour ce scénario, suivez les étapes de la section Vérifier le document de stratégie basé sur les ressources correspondant à votre fonction Lambda.
  • Les appels de vos fonctions Lambda sont retardés. Pour ce scénario, suivez les étapes de la section Vérifier vos journaux de diffusion Amazon SNS.

Remarque : la résolution suivante présuppose que vous pouvez appeler l'API Publish (Publier) sur votre rubrique SNS, mais que vous obtenez des erreurs entre l'intégration Amazon SNS et Lambda. Si vous ne voyez aucune activité sur votre rubrique SNS, consultez Pourquoi n'ai-je pas reçu de notification SNS pour mon déclencheur d'alarme CloudWatch ?  Cette activité peut inclure les métriques CloudWatch suivantes : NumberOfMessagesPublished, NumberOfNotificationsDelivered ou NumberOfNotificationsFailed.

Solution

Remarque : si vous recevez des erreurs lors de l'exécution de commandes à partir de l'AWS Command Line Interface (AWS CLI), assurez-vous d'utiliser la version la plus récente d'AWS CLI.

Vérifiez le document de stratégie basé sur les ressources correspondant à votre fonction Lambda

Lorsqu'Amazon SNS appelle une fonction Lambda de manière asynchrone, Lambda renvoie un code d'état HTTP 202 à Amazon SNS. Le code d'état indique que Lambda a accepté le message pour traitement ultérieur. Pour plus d'informations, consultez Appel asynchrone. En cas d'échec de réponse, vous pouvez vérifier vos journaux de diffusion Amazon SNS pour obtenir plus d'informations.

Choisissez une solution basée sur le scénario correspondant à votre compte.

Si votre rubrique SNS et votre fonction Lambda se trouvent dans le même compte :

1.    Ouvrez la console Lambda.

2.    Dans le panneau de navigation, sélectionnez Functions (Fonctions), puis choisissez votre fonction.

3.    Sélectionnez l'onglet Configuration, puis Permissions (Autorisations).

4.    Dans la section Resource-based policy (Stratégie basée sur les ressources), sélectionnez la déclaration de stratégie dans la colonne Statement ID (ID de déclaration) pour afficher votre document de stratégie. Le document de stratégie suivant s'affiche :

statement id
your-statement-id

principal:
sns.amazonaws.com

effect
allow

action
Lambda:InvokeFunction

conditions
{ "arnlike": { "aws:sourcearn": "arn:aws:sns:your-aws-region:your-aws-account-id:your-sns-topic-name" } 

Remarque : pour afficher votre document de stratégie au format JSON, sélectionnez View policy document (Afficher le document de stratégie) dans la section Resource-based policy (Stratégie basée sur les ressources).

Si vous ne disposez pas de la stratégie de ressources Lambda qui autorise Amazon SNS à appeler la fonction, ajoutez la fonction suivante à votre document de stratégie. Vous pouvez utiliser la console Lambda, l'AWS CLI ou AWS CloudShell.

À l'aide de la ligne de commande :

aws lambda add-permission \
--function-name your-lambda-function-name \
--statement-id triggerfromsns-statement-id \
--action lambda:invokefunction \
--principal sns.amazonaws.com \
--source-arn arn:aws:sns:your-aws-region:your-aws-account-id:your-sns-topic-name

Remarque : remplacez your-lambda-function-name, your-aws-region, your-aws-account-id et your-sns-topic-name par vos valeurs. La commande AWS CLI utilise la région AWS par défaut. Vous pouvez remplacer la région par défaut par l'indicateur --region si votre fonction Lambda se trouve dans une autre région.

À l'aide de la console Lambda :

1.    Ouvrez la console Lambda.

2.    Dans le panneau de navigation, sélectionnez Functions (Fonctions), puis choisissez votre fonction.

3.    Sélectionnez l'onglet Configuration, puis Permissions (Autorisations).

4.    Dans la section Resource-based policy (Stratégie basée sur les ressources), sélectionnez Add permissions (Ajouter des autorisations).

5.    Pour Principal, sélectionnez sns.amazonaws.com.

6.    Pour Actions, sélectionnez Lambda:InvokeFunction.

7.    Pour Statement ID (ID de déclaration), saisissez un ID unique.

8.    Sélectionnez Save (Enregistrer).

Si votre rubrique SNS et votre fonction Lambda se trouvent dans des comptes différents :

1.    Configurez des autorisations entre comptes.

2.    Dans vos journaux CloudWatch, utilisez la journalisation du statut de diffusion pour vérifier qu'Amazon SNS a bien envoyé un message à Lambda ou utilisez la métrique CloudWatch NumberOfNotificationsDelivered.

Exemple de réponse aboutit entre Amazon SNS et Lambda :

{
    "notification": {
        "messagemd5sum": "your-md5-sum",
        "messageid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
        "topicarn": "arn:aws:sns:your-aws-region:your-aws-account-id:your-sns-topic",
        "timestamp": "2021-04-04 14:08:48.083"
    },
    "delivery": {
        "deliveryid": "your-sns-delivery-id",
        "destination": "arn:aws:lambda:your-aws-region:your-aws-account-id:function:your-function-name",
        "providerresponse": "{\ "lambdarequestid\":\ "your-lambda-request-id\"}",
        "dwelltimems": 92,
        "attempts": 1,
        "statuscode": 202
    },
        "status": "success"
}

Vérifier vos journaux de diffusion Amazon SNS

Vérifiez les journaux de diffusion de votre rubrique SNS vers votre fonction Lambda. Si la réponse aboutit, un code d'état 202 s'affiche.

Afin d'afficher les journaux CloudWatch pour votre rubrique SNS, procédez comme suit :

1.    Ouvrez la console CloudWatch.

2.    Dans le panneau de navigation, développez Logs (Journaux), puis sélectionnez Log groups (Groupes de journaux).

3.    Dans la zone de recherche avec filtre, saisissez le nom de votre rubrique SNS. Deux groupes de journaux pour votre rubrique SNS apparaissent : l'un pour les réussites et l'autre pour les échecs.

4.    Sélectionnez le groupe de journaux liés aux réussites.

5.    Dans la section Log streams (Flux de journaux), sélectionnez Search all (Rechercher tout).

Remarque : vous pouvez également vérifier l'horodatage de la demande dans la colonne Last event time (Heure du dernier événement). Ensuite, recherchez l'Amazon Resource Name (ARN) et le nom de la fonction Lambda.

6.    Dans la colonne Log stream (Flux de journaux), sélectionnez le flux de journaux afin de l'ouvrir.

Si vous ne voyez aucun résultat, procédez comme suit :

1.    Sélectionnez Log groups (Groupes de journaux), puis choisissez les groupes de journaux liés aux échecs.

2.    Dans la section Log streams (Flux de journaux), sélectionnez Search all (Rechercher tout).

3.    Dans la colonne Log stream (Flux de journaux), sélectionnez le flux de journaux afin de l'ouvrir.

Pour résoudre les problèmes des groupes de journaux liés aux échecs, procédez comme suit :

1.    Vérifiez si le suivi X-Ray de votre fonction Lambda a un temps d'arrêt élevé. Si le temps d'arrêt est élevé, utilisez la console CloudWatch pour vérifier que vos fonctions Lambda dans cette région possèdent le moins d'erreurs et de limitations. Veillez à sélectionner toutes les fonctions, puis sélectionnez les métriques Errors (Erreurs) et Throttles (Limitations).

Remarque : des centaines d'erreurs et de limitations entre les fonctions appelées de manière asynchrone peuvent sauvegarder la file d'attente Lambda interne, ce qui entraîne des retards dans les appels de fonctions. Il est recommandé de réduire au minimum le taux d'erreur et de limitation, afin d'éviter les retards indésirables pour les appels de fonctions. Pour plus d'informations, consultez Appel asynchrone.

2.    Définissez une file d'attente Amazon Simple Queue Service (Amazon SQS) de destination ou une fonction Lambda pour une gestion séparée. Cela évite la perte de messages et doit être mis en œuvre car l'âge maximum des événements asynchrones peut être de six heures pour une fonction Lambda.


Cet article vous a-t-il été utile ?


Besoin d'aide pour une question technique ou de facturation ?