Tech Talk: Construire une architecture sans serveur sur AWS avec interaction des fonctions lambda (Partie 2)

Tech Talk: Construire une architecture sans serveur sur AWS avec interaction des fonctions lambda (Partie 2)

Comment construire une architecture sans serveur en utilisant les fonctions Lambda d'AWS (FaaS dans la nomenclature d'AWS), le service SQS, les Step Functions, et plus encore.

Comment construire une architecture sans serveur en utilisant les fonctions Lambda d'AWS (FaaS dans la nomenclature d'AWS), le service SQS, les Step Functions, et plus encore.

Comment construire une architecture sans serveur en utilisant les fonctions Lambda d'AWS (FaaS dans la nomenclature d'AWS), le service SQS, les Step Functions, et plus encore.

Dans la première partie de cette série d'articles, nous avons discuté de la manière dont la fonction Lambda sert de fondation aux architectures sans serveur dans le cloud. Maintenant, nous allons explorer comment les interactions entre les fonctions Lambda et les files d'attente constituent l'étape suivante pour construire une architecture sans serveur robuste.

Simple Queuing Service (SQS) sur AWS

Nous avons terminé la première partie de cet article face à un goulot d'étranglement : nos événements ne pouvaient pas être gérés par l'architecture sans serveur simple en place. La solution la plus simple pour résoudre le problème des messages manquants est de tirer parti d'un service de files d'attente de messages. AWS appelle ce service Simple Queuing Service, ou SQS en abrégé. Il résout le problème des goulots d'étranglement en envoyant, recevant et stockant des messages entre logiciels sans perdre de messages ni exiger que les services soient disponibles. Si la deuxième fonction Lambda dans l'exemple précédent est occupée avec les premiers 1 000 travaux qu'elle a reçus, SQS garde patiemment les 4 000 travaux suivants jusqu'à ce que 'ListenerLambda' puisse les ingérer.

Nous pouvons envoyer le message à SQS de manière programmatique en utilisant l'AWS SDK depuis la fonction Lambda;

client = boto3.client('sqs')

client.send_message(QueueUrl='string', MessageBody='{"file": "path"})

où ‘QueueUrl’ est l'URL correspondant à la file d'attente particulière que nous voulons utiliser (encore une fois, consultez la documentation pour d'autres options que nous ne développons pas dans cet exemple). Pour que la deuxième fonction Lambda écoute cette file d'attente, nous pouvons, à nouveau, aller à l'écran console montré dans la Figure 4, cliquer sur ‘Ajouter un déclencheur’ et sélectionner là l'SQS d'intérêt.

C'est aussi simple que cela, nous avons réussi à résoudre le problème du goulot d'étranglement. Lorsque l'événement est traité dans la fonction auditeur, il est automatiquement retiré de la file pour éviter de l'envoyer à nouveau. Si pour une raison quelconque, l'auditeur Lambda n'a pas terminé le traitement de l'événement (il soulève une erreur), alors la file réessaiera de l'envoyer plus tard.

C'est génial... n'est-ce pas? Les choses peuvent se compliquer dans de nombreux cas. Imaginez que 'ListenerLambda' ne réussisse à traiter que 99% des événements qu'il reçoit du premier Lambda, et qu'un événement qui a échoué une fois échoue toujours. Dans cette situation, le message est renvoyé à la file, qui l'envoie à 'ListenerLambda', qui échoue, donc le message est renvoyé à la file... vous le voyez, non? Pour éviter ce cercle vicieux, le SQS est équipé d'une période de rétention qui efface automatiquement les messages qui n'ont pas été traités pendant cette période (Figure 5).

Figure 5 : Configuration de SQS

Imaginez que vous avez estimé que tous vos travaux se terminent en deux jours s'ils sont sans erreur. Vous supposeriez donc que tout message existant encore dans la file après deux jours est dû à l'échec d'un travail et peut être effacé en toute sécurité. Vous réglez donc votre période de rétention sur deux jours. Cela résout le problème mais n'est pas une bonne pratique. Comment pouvez-vous déboguer votre code et l'améliorer si vous avez effacé toutes les informations sur le type d'événements qui ont causé l'erreur à l'origine?

Encore une fois, pas de souci, nous ne sommes pas les premiers à y avoir pensé. En faisant défiler l'écran de la console AWS, vous trouverez la possibilité de configurer une File d'Attente de Messages Morts pour votre SQS. C'est juste une autre SQS à laquelle vous redirigez les événements problématiques. En configurant une longue période de rétention dans la File d'Attente de Messages Morts, vous pouvez surveiller votre travail à tout moment sans craindre que des événements qui n'ont pas été gérés correctement par votre code soient continuellement envoyés à votre fonction Lambda.

Félicitations! Avec cela, nous avons réussi à permettre à deux fonctions Lambda de se parler de manière robuste, en gérant les goulots d'étranglement et les événements problématiques avec SQS et les Files d'Attente de Messages Morts.

Si vous regardez en arrière votre cas d'utilisation et constatez que vous avez des dizaines de fonctions Lambda prêtes à être déployées, avec une logique non séquentielle les connectant, et que vous devez gérer la capture et le réessai d'erreurs, vous pourriez penser que les outils à votre disposition sont limités. C'est vrai. Ce qui se passe, c'est que nous n'avons pas encore introduit la Fonction de Pas d'AWS.

Fonction de Pas d'AWS

La Fonction de Pas d'AWS est un orchestrateur pour les fonctions sans serveur. Vous pouvez coordonner visuellement les Lambdas et d'autres services sans serveur AWS rapidement. Le terme clé ici est ‘visuellement’, car son interface graphique clarifie ce qui se passe à chaque instant, que ce soit une fonction Lambda envoyant un événement à la suivante, capturant une erreur et réessayant ou implémentant une logique si-alors-sinon, pour donner quelques exemples. La figure 6 présente une capture d'écran de la page de configuration, où vous pouvez trouver plusieurs modèles d'exemple pour commencer et découvrir les possibilités que ce service permet.

Figure 6 : Orchestration de fonctions Lambda avec Fonction de Pas d'AWS

Il fait tout cela, gérant automatiquement les événements entre les fonctions sans serveur. Pas besoin de tout ce bla-bla que vous venez de lire! En tant que tel, c'est un outil très puissant pour orchestrer vos Lambdas. Alors, pourquoi ne pas l'utiliser toujours pour simplifier notre code et gagner du temps à lire cet article? La raison est que cette solution a un coût, vous devez donc équilibrer combien vous voulez payer et combien de gestion vous êtes prêt à supporter. Cette option vaut certainement le coup pour des flux de travail modérément compliqués.

Autorisations minimales avec AWS

Nous terminons cet article avec le sujet le plus important de tous : la sécurité. Suivre des tutoriels et modèles en ligne est un excellent moyen d'apprendre à déployer une infrastructure, mais ceux-ci favorisent généralement le déploiement rapide d'un pipeline au détriment de considérations telles que la sécurité. Après tout, c'est un tutoriel et vous allez détruire toutes les ressources créées (le cloud est un endroit dangereux: détruisez toujours toutes les ressources que vous n'utiliserez pas). Dans le contexte actuel, cela signifie que pour qu'une fonction Lambda interagisse avec une file d'attente SQS, il serait demandé de se rendre dans la console IAM d'AWS, et d'y attribuer une politique de sécurité intégrée au rôle de la fonction Lambda, souvent celle avec le plein accès, comme dans la Figure 7.

Figure 7 : Autoriser une Lambda à interagir avec SQS

Après avoir attribué cette politique au rôle Lambda, vous pouvez trouver son contenu au format JSON dans la console IAM, où il lira quelque chose de similaire à :

{
   "Version": "2012-10-17",
   "Statement": [
       {
           "Effect": "Allow",
           "Action": [
               "sqs:*"
           ],
           "Resource": "*"
       }
   ]
}

Le problème de sécurité avec ce type de politique réside dans les jokers ‘*’. En particulier, "sqs:*" permet à la Lambda d'interagir avec la file d'attente SQS sans restriction. Il est même possible de l'effacer ou de créer plus de messages pour que la Lambda les consomme, aboutissant à une boucle infinie ! Ce qui est pire, le second joker dans "Resource": "*" permet à la fonction Lambda d'interagir avec n'importe quelle file d'attente, de sorte qu'il existe une réelle possibilité que nous invoquions la fonction sans serveur avec les mauvais événements destinés à une fonction différente ou, pire encore, à un projet complètement indépendant.

Figure 8 : Autoriser une Lambda à interagir avec SQS

Vous pouvez atténuer le premier de ces problèmes en choisissant plutôt le rôle d'exécution de la file SQS, comme illustré dans la Figure 8. Dans ce cas, l'ensemble des actions que la Lambda peut exécuter concernant le SQS est limité. Le résumé JSON des politiques autorisées se lit maintenant :

{
   "Version": "2012-10-17",
   "Statement": [
       {
           "Effect": "Allow",
           "Action": [
               "sqs:ReceiveMessage",
               "sqs:DeleteMessage",
               "sqs:GetQueueAttributes"
           ],
           "Resource": "*"
       }
   ]
}

Cela permet de recevoir des messages, de supprimer des messages ou d'obtenir les attributs de la file (plus de suppression de la file ou de création accidentelle de nouveaux messages). Le seul point faible restant ici est le terme "Resource": "*" qui permet à la Lambda d'interagir avec n'importe quelle file. Nous pouvons résoudre cela en limitant la politique à une ressource particulière : le SQS que la Lambda est censée lire les messages. Pour ce faire, vous devez obtenir l'ARN du SQS, ce qui peut être fait dans la console AWS, comme illustré dans la Figure 9.

Figure 9 : Obtention de l'ARN d'une file d'attente SQS

En inscrivant ce code ARN à la place du joker ‘*’ dans le champ Resource de la politique, vous vous assurez que la fonction Lambda ne peut recevoir des messages, supprimer des messages et obtenir les attributs de la file que de cette file. Une remarque finale vient de la question évidente : que faire si je veux lire des messages d'une file et envoyer des messages à une autre, par exemple pour invoquer une troisième fonction Lambda? Ne limitera-t-on pas la ressource à la file de réception, ce qui serait contre-productif alors? La réponse est simple, vous pouvez attacher plus de politiques à votre rôle Lambda. Par exemple, vous pouvez ajouter la permission d'envoyer des messages à une file différente, dans les lignes :

{
   "Version": "2012-10-17",
   "Statement": [
       {
           "Effect": "Allow",
           "Action": [
               "sqs:ChangeMessageVisibility",
               "sqs:DeleteMessage",
               "sqs:GetQueueAttributes",
               "sqs:ReceiveMessage"
           ],
           "Resource": "ARN_DE_LA_FILE_POUR_LIRE_LES_MESSAGES"
       },
       {
           "Effect": "Allow",
           "Action": [
               "sqs:SendMessage"
           ],
           "Resource": "ARN_DE_LA_FILE_VERS_LAQUELLE_ENVOYER_LES_MESSAGES"
       }
}

Limitez toujours les actions autorisées par votre politique et les ressources au minimum nécessaire. Vous éviterez d'avoir des problèmes à l'avenir lors du passage de votre application à la production.

Conclusion

Nous avons vu comment construire des architectures sans serveur robustes et efficaces dans le cloud en utilisant des fonctions Lambda, le service SQS, les fonctions de pas et un paramétrage restrictif des permissions.

Pour les charges de travail qui sont irrégulières ou ont de longues périodes d'inactivité, cela offre une alternative rentable et facile à gérer par rapport au déploiement de morceaux de code monolithiques dans des machines virtuelles.

Dans cet article, nous nous sommes concentrés sur l'environnement AWS pour l'illustration, mais ces commentaires se traduisent directement vers d'autres fournisseurs de services cloud comme MS Azure (voir article: description d'un cas d'utilisation) ou Google Cloud.

Dans la première partie de cette série d'articles, nous avons discuté de la manière dont la fonction Lambda sert de fondation aux architectures sans serveur dans le cloud. Maintenant, nous allons explorer comment les interactions entre les fonctions Lambda et les files d'attente constituent l'étape suivante pour construire une architecture sans serveur robuste.

Simple Queuing Service (SQS) sur AWS

Nous avons terminé la première partie de cet article face à un goulot d'étranglement : nos événements ne pouvaient pas être gérés par l'architecture sans serveur simple en place. La solution la plus simple pour résoudre le problème des messages manquants est de tirer parti d'un service de files d'attente de messages. AWS appelle ce service Simple Queuing Service, ou SQS en abrégé. Il résout le problème des goulots d'étranglement en envoyant, recevant et stockant des messages entre logiciels sans perdre de messages ni exiger que les services soient disponibles. Si la deuxième fonction Lambda dans l'exemple précédent est occupée avec les premiers 1 000 travaux qu'elle a reçus, SQS garde patiemment les 4 000 travaux suivants jusqu'à ce que 'ListenerLambda' puisse les ingérer.

Nous pouvons envoyer le message à SQS de manière programmatique en utilisant l'AWS SDK depuis la fonction Lambda;

client = boto3.client('sqs')

client.send_message(QueueUrl='string', MessageBody='{"file": "path"})

où ‘QueueUrl’ est l'URL correspondant à la file d'attente particulière que nous voulons utiliser (encore une fois, consultez la documentation pour d'autres options que nous ne développons pas dans cet exemple). Pour que la deuxième fonction Lambda écoute cette file d'attente, nous pouvons, à nouveau, aller à l'écran console montré dans la Figure 4, cliquer sur ‘Ajouter un déclencheur’ et sélectionner là l'SQS d'intérêt.

C'est aussi simple que cela, nous avons réussi à résoudre le problème du goulot d'étranglement. Lorsque l'événement est traité dans la fonction auditeur, il est automatiquement retiré de la file pour éviter de l'envoyer à nouveau. Si pour une raison quelconque, l'auditeur Lambda n'a pas terminé le traitement de l'événement (il soulève une erreur), alors la file réessaiera de l'envoyer plus tard.

C'est génial... n'est-ce pas? Les choses peuvent se compliquer dans de nombreux cas. Imaginez que 'ListenerLambda' ne réussisse à traiter que 99% des événements qu'il reçoit du premier Lambda, et qu'un événement qui a échoué une fois échoue toujours. Dans cette situation, le message est renvoyé à la file, qui l'envoie à 'ListenerLambda', qui échoue, donc le message est renvoyé à la file... vous le voyez, non? Pour éviter ce cercle vicieux, le SQS est équipé d'une période de rétention qui efface automatiquement les messages qui n'ont pas été traités pendant cette période (Figure 5).

Figure 5 : Configuration de SQS

Imaginez que vous avez estimé que tous vos travaux se terminent en deux jours s'ils sont sans erreur. Vous supposeriez donc que tout message existant encore dans la file après deux jours est dû à l'échec d'un travail et peut être effacé en toute sécurité. Vous réglez donc votre période de rétention sur deux jours. Cela résout le problème mais n'est pas une bonne pratique. Comment pouvez-vous déboguer votre code et l'améliorer si vous avez effacé toutes les informations sur le type d'événements qui ont causé l'erreur à l'origine?

Encore une fois, pas de souci, nous ne sommes pas les premiers à y avoir pensé. En faisant défiler l'écran de la console AWS, vous trouverez la possibilité de configurer une File d'Attente de Messages Morts pour votre SQS. C'est juste une autre SQS à laquelle vous redirigez les événements problématiques. En configurant une longue période de rétention dans la File d'Attente de Messages Morts, vous pouvez surveiller votre travail à tout moment sans craindre que des événements qui n'ont pas été gérés correctement par votre code soient continuellement envoyés à votre fonction Lambda.

Félicitations! Avec cela, nous avons réussi à permettre à deux fonctions Lambda de se parler de manière robuste, en gérant les goulots d'étranglement et les événements problématiques avec SQS et les Files d'Attente de Messages Morts.

Si vous regardez en arrière votre cas d'utilisation et constatez que vous avez des dizaines de fonctions Lambda prêtes à être déployées, avec une logique non séquentielle les connectant, et que vous devez gérer la capture et le réessai d'erreurs, vous pourriez penser que les outils à votre disposition sont limités. C'est vrai. Ce qui se passe, c'est que nous n'avons pas encore introduit la Fonction de Pas d'AWS.

Fonction de Pas d'AWS

La Fonction de Pas d'AWS est un orchestrateur pour les fonctions sans serveur. Vous pouvez coordonner visuellement les Lambdas et d'autres services sans serveur AWS rapidement. Le terme clé ici est ‘visuellement’, car son interface graphique clarifie ce qui se passe à chaque instant, que ce soit une fonction Lambda envoyant un événement à la suivante, capturant une erreur et réessayant ou implémentant une logique si-alors-sinon, pour donner quelques exemples. La figure 6 présente une capture d'écran de la page de configuration, où vous pouvez trouver plusieurs modèles d'exemple pour commencer et découvrir les possibilités que ce service permet.

Figure 6 : Orchestration de fonctions Lambda avec Fonction de Pas d'AWS

Il fait tout cela, gérant automatiquement les événements entre les fonctions sans serveur. Pas besoin de tout ce bla-bla que vous venez de lire! En tant que tel, c'est un outil très puissant pour orchestrer vos Lambdas. Alors, pourquoi ne pas l'utiliser toujours pour simplifier notre code et gagner du temps à lire cet article? La raison est que cette solution a un coût, vous devez donc équilibrer combien vous voulez payer et combien de gestion vous êtes prêt à supporter. Cette option vaut certainement le coup pour des flux de travail modérément compliqués.

Autorisations minimales avec AWS

Nous terminons cet article avec le sujet le plus important de tous : la sécurité. Suivre des tutoriels et modèles en ligne est un excellent moyen d'apprendre à déployer une infrastructure, mais ceux-ci favorisent généralement le déploiement rapide d'un pipeline au détriment de considérations telles que la sécurité. Après tout, c'est un tutoriel et vous allez détruire toutes les ressources créées (le cloud est un endroit dangereux: détruisez toujours toutes les ressources que vous n'utiliserez pas). Dans le contexte actuel, cela signifie que pour qu'une fonction Lambda interagisse avec une file d'attente SQS, il serait demandé de se rendre dans la console IAM d'AWS, et d'y attribuer une politique de sécurité intégrée au rôle de la fonction Lambda, souvent celle avec le plein accès, comme dans la Figure 7.

Figure 7 : Autoriser une Lambda à interagir avec SQS

Après avoir attribué cette politique au rôle Lambda, vous pouvez trouver son contenu au format JSON dans la console IAM, où il lira quelque chose de similaire à :

{
   "Version": "2012-10-17",
   "Statement": [
       {
           "Effect": "Allow",
           "Action": [
               "sqs:*"
           ],
           "Resource": "*"
       }
   ]
}

Le problème de sécurité avec ce type de politique réside dans les jokers ‘*’. En particulier, "sqs:*" permet à la Lambda d'interagir avec la file d'attente SQS sans restriction. Il est même possible de l'effacer ou de créer plus de messages pour que la Lambda les consomme, aboutissant à une boucle infinie ! Ce qui est pire, le second joker dans "Resource": "*" permet à la fonction Lambda d'interagir avec n'importe quelle file d'attente, de sorte qu'il existe une réelle possibilité que nous invoquions la fonction sans serveur avec les mauvais événements destinés à une fonction différente ou, pire encore, à un projet complètement indépendant.

Figure 8 : Autoriser une Lambda à interagir avec SQS

Vous pouvez atténuer le premier de ces problèmes en choisissant plutôt le rôle d'exécution de la file SQS, comme illustré dans la Figure 8. Dans ce cas, l'ensemble des actions que la Lambda peut exécuter concernant le SQS est limité. Le résumé JSON des politiques autorisées se lit maintenant :

{
   "Version": "2012-10-17",
   "Statement": [
       {
           "Effect": "Allow",
           "Action": [
               "sqs:ReceiveMessage",
               "sqs:DeleteMessage",
               "sqs:GetQueueAttributes"
           ],
           "Resource": "*"
       }
   ]
}

Cela permet de recevoir des messages, de supprimer des messages ou d'obtenir les attributs de la file (plus de suppression de la file ou de création accidentelle de nouveaux messages). Le seul point faible restant ici est le terme "Resource": "*" qui permet à la Lambda d'interagir avec n'importe quelle file. Nous pouvons résoudre cela en limitant la politique à une ressource particulière : le SQS que la Lambda est censée lire les messages. Pour ce faire, vous devez obtenir l'ARN du SQS, ce qui peut être fait dans la console AWS, comme illustré dans la Figure 9.

Figure 9 : Obtention de l'ARN d'une file d'attente SQS

En inscrivant ce code ARN à la place du joker ‘*’ dans le champ Resource de la politique, vous vous assurez que la fonction Lambda ne peut recevoir des messages, supprimer des messages et obtenir les attributs de la file que de cette file. Une remarque finale vient de la question évidente : que faire si je veux lire des messages d'une file et envoyer des messages à une autre, par exemple pour invoquer une troisième fonction Lambda? Ne limitera-t-on pas la ressource à la file de réception, ce qui serait contre-productif alors? La réponse est simple, vous pouvez attacher plus de politiques à votre rôle Lambda. Par exemple, vous pouvez ajouter la permission d'envoyer des messages à une file différente, dans les lignes :

{
   "Version": "2012-10-17",
   "Statement": [
       {
           "Effect": "Allow",
           "Action": [
               "sqs:ChangeMessageVisibility",
               "sqs:DeleteMessage",
               "sqs:GetQueueAttributes",
               "sqs:ReceiveMessage"
           ],
           "Resource": "ARN_DE_LA_FILE_POUR_LIRE_LES_MESSAGES"
       },
       {
           "Effect": "Allow",
           "Action": [
               "sqs:SendMessage"
           ],
           "Resource": "ARN_DE_LA_FILE_VERS_LAQUELLE_ENVOYER_LES_MESSAGES"
       }
}

Limitez toujours les actions autorisées par votre politique et les ressources au minimum nécessaire. Vous éviterez d'avoir des problèmes à l'avenir lors du passage de votre application à la production.

Conclusion

Nous avons vu comment construire des architectures sans serveur robustes et efficaces dans le cloud en utilisant des fonctions Lambda, le service SQS, les fonctions de pas et un paramétrage restrictif des permissions.

Pour les charges de travail qui sont irrégulières ou ont de longues périodes d'inactivité, cela offre une alternative rentable et facile à gérer par rapport au déploiement de morceaux de code monolithiques dans des machines virtuelles.

Dans cet article, nous nous sommes concentrés sur l'environnement AWS pour l'illustration, mais ces commentaires se traduisent directement vers d'autres fournisseurs de services cloud comme MS Azure (voir article: description d'un cas d'utilisation) ou Google Cloud.

Dans la première partie de cette série d'articles, nous avons discuté de la manière dont la fonction Lambda sert de fondation aux architectures sans serveur dans le cloud. Maintenant, nous allons explorer comment les interactions entre les fonctions Lambda et les files d'attente constituent l'étape suivante pour construire une architecture sans serveur robuste.

Simple Queuing Service (SQS) sur AWS

Nous avons terminé la première partie de cet article face à un goulot d'étranglement : nos événements ne pouvaient pas être gérés par l'architecture sans serveur simple en place. La solution la plus simple pour résoudre le problème des messages manquants est de tirer parti d'un service de files d'attente de messages. AWS appelle ce service Simple Queuing Service, ou SQS en abrégé. Il résout le problème des goulots d'étranglement en envoyant, recevant et stockant des messages entre logiciels sans perdre de messages ni exiger que les services soient disponibles. Si la deuxième fonction Lambda dans l'exemple précédent est occupée avec les premiers 1 000 travaux qu'elle a reçus, SQS garde patiemment les 4 000 travaux suivants jusqu'à ce que 'ListenerLambda' puisse les ingérer.

Nous pouvons envoyer le message à SQS de manière programmatique en utilisant l'AWS SDK depuis la fonction Lambda;

client = boto3.client('sqs')

client.send_message(QueueUrl='string', MessageBody='{"file": "path"})

où ‘QueueUrl’ est l'URL correspondant à la file d'attente particulière que nous voulons utiliser (encore une fois, consultez la documentation pour d'autres options que nous ne développons pas dans cet exemple). Pour que la deuxième fonction Lambda écoute cette file d'attente, nous pouvons, à nouveau, aller à l'écran console montré dans la Figure 4, cliquer sur ‘Ajouter un déclencheur’ et sélectionner là l'SQS d'intérêt.

C'est aussi simple que cela, nous avons réussi à résoudre le problème du goulot d'étranglement. Lorsque l'événement est traité dans la fonction auditeur, il est automatiquement retiré de la file pour éviter de l'envoyer à nouveau. Si pour une raison quelconque, l'auditeur Lambda n'a pas terminé le traitement de l'événement (il soulève une erreur), alors la file réessaiera de l'envoyer plus tard.

C'est génial... n'est-ce pas? Les choses peuvent se compliquer dans de nombreux cas. Imaginez que 'ListenerLambda' ne réussisse à traiter que 99% des événements qu'il reçoit du premier Lambda, et qu'un événement qui a échoué une fois échoue toujours. Dans cette situation, le message est renvoyé à la file, qui l'envoie à 'ListenerLambda', qui échoue, donc le message est renvoyé à la file... vous le voyez, non? Pour éviter ce cercle vicieux, le SQS est équipé d'une période de rétention qui efface automatiquement les messages qui n'ont pas été traités pendant cette période (Figure 5).

Figure 5 : Configuration de SQS

Imaginez que vous avez estimé que tous vos travaux se terminent en deux jours s'ils sont sans erreur. Vous supposeriez donc que tout message existant encore dans la file après deux jours est dû à l'échec d'un travail et peut être effacé en toute sécurité. Vous réglez donc votre période de rétention sur deux jours. Cela résout le problème mais n'est pas une bonne pratique. Comment pouvez-vous déboguer votre code et l'améliorer si vous avez effacé toutes les informations sur le type d'événements qui ont causé l'erreur à l'origine?

Encore une fois, pas de souci, nous ne sommes pas les premiers à y avoir pensé. En faisant défiler l'écran de la console AWS, vous trouverez la possibilité de configurer une File d'Attente de Messages Morts pour votre SQS. C'est juste une autre SQS à laquelle vous redirigez les événements problématiques. En configurant une longue période de rétention dans la File d'Attente de Messages Morts, vous pouvez surveiller votre travail à tout moment sans craindre que des événements qui n'ont pas été gérés correctement par votre code soient continuellement envoyés à votre fonction Lambda.

Félicitations! Avec cela, nous avons réussi à permettre à deux fonctions Lambda de se parler de manière robuste, en gérant les goulots d'étranglement et les événements problématiques avec SQS et les Files d'Attente de Messages Morts.

Si vous regardez en arrière votre cas d'utilisation et constatez que vous avez des dizaines de fonctions Lambda prêtes à être déployées, avec une logique non séquentielle les connectant, et que vous devez gérer la capture et le réessai d'erreurs, vous pourriez penser que les outils à votre disposition sont limités. C'est vrai. Ce qui se passe, c'est que nous n'avons pas encore introduit la Fonction de Pas d'AWS.

Fonction de Pas d'AWS

La Fonction de Pas d'AWS est un orchestrateur pour les fonctions sans serveur. Vous pouvez coordonner visuellement les Lambdas et d'autres services sans serveur AWS rapidement. Le terme clé ici est ‘visuellement’, car son interface graphique clarifie ce qui se passe à chaque instant, que ce soit une fonction Lambda envoyant un événement à la suivante, capturant une erreur et réessayant ou implémentant une logique si-alors-sinon, pour donner quelques exemples. La figure 6 présente une capture d'écran de la page de configuration, où vous pouvez trouver plusieurs modèles d'exemple pour commencer et découvrir les possibilités que ce service permet.

Figure 6 : Orchestration de fonctions Lambda avec Fonction de Pas d'AWS

Il fait tout cela, gérant automatiquement les événements entre les fonctions sans serveur. Pas besoin de tout ce bla-bla que vous venez de lire! En tant que tel, c'est un outil très puissant pour orchestrer vos Lambdas. Alors, pourquoi ne pas l'utiliser toujours pour simplifier notre code et gagner du temps à lire cet article? La raison est que cette solution a un coût, vous devez donc équilibrer combien vous voulez payer et combien de gestion vous êtes prêt à supporter. Cette option vaut certainement le coup pour des flux de travail modérément compliqués.

Autorisations minimales avec AWS

Nous terminons cet article avec le sujet le plus important de tous : la sécurité. Suivre des tutoriels et modèles en ligne est un excellent moyen d'apprendre à déployer une infrastructure, mais ceux-ci favorisent généralement le déploiement rapide d'un pipeline au détriment de considérations telles que la sécurité. Après tout, c'est un tutoriel et vous allez détruire toutes les ressources créées (le cloud est un endroit dangereux: détruisez toujours toutes les ressources que vous n'utiliserez pas). Dans le contexte actuel, cela signifie que pour qu'une fonction Lambda interagisse avec une file d'attente SQS, il serait demandé de se rendre dans la console IAM d'AWS, et d'y attribuer une politique de sécurité intégrée au rôle de la fonction Lambda, souvent celle avec le plein accès, comme dans la Figure 7.

Figure 7 : Autoriser une Lambda à interagir avec SQS

Après avoir attribué cette politique au rôle Lambda, vous pouvez trouver son contenu au format JSON dans la console IAM, où il lira quelque chose de similaire à :

{
   "Version": "2012-10-17",
   "Statement": [
       {
           "Effect": "Allow",
           "Action": [
               "sqs:*"
           ],
           "Resource": "*"
       }
   ]
}

Le problème de sécurité avec ce type de politique réside dans les jokers ‘*’. En particulier, "sqs:*" permet à la Lambda d'interagir avec la file d'attente SQS sans restriction. Il est même possible de l'effacer ou de créer plus de messages pour que la Lambda les consomme, aboutissant à une boucle infinie ! Ce qui est pire, le second joker dans "Resource": "*" permet à la fonction Lambda d'interagir avec n'importe quelle file d'attente, de sorte qu'il existe une réelle possibilité que nous invoquions la fonction sans serveur avec les mauvais événements destinés à une fonction différente ou, pire encore, à un projet complètement indépendant.

Figure 8 : Autoriser une Lambda à interagir avec SQS

Vous pouvez atténuer le premier de ces problèmes en choisissant plutôt le rôle d'exécution de la file SQS, comme illustré dans la Figure 8. Dans ce cas, l'ensemble des actions que la Lambda peut exécuter concernant le SQS est limité. Le résumé JSON des politiques autorisées se lit maintenant :

{
   "Version": "2012-10-17",
   "Statement": [
       {
           "Effect": "Allow",
           "Action": [
               "sqs:ReceiveMessage",
               "sqs:DeleteMessage",
               "sqs:GetQueueAttributes"
           ],
           "Resource": "*"
       }
   ]
}

Cela permet de recevoir des messages, de supprimer des messages ou d'obtenir les attributs de la file (plus de suppression de la file ou de création accidentelle de nouveaux messages). Le seul point faible restant ici est le terme "Resource": "*" qui permet à la Lambda d'interagir avec n'importe quelle file. Nous pouvons résoudre cela en limitant la politique à une ressource particulière : le SQS que la Lambda est censée lire les messages. Pour ce faire, vous devez obtenir l'ARN du SQS, ce qui peut être fait dans la console AWS, comme illustré dans la Figure 9.

Figure 9 : Obtention de l'ARN d'une file d'attente SQS

En inscrivant ce code ARN à la place du joker ‘*’ dans le champ Resource de la politique, vous vous assurez que la fonction Lambda ne peut recevoir des messages, supprimer des messages et obtenir les attributs de la file que de cette file. Une remarque finale vient de la question évidente : que faire si je veux lire des messages d'une file et envoyer des messages à une autre, par exemple pour invoquer une troisième fonction Lambda? Ne limitera-t-on pas la ressource à la file de réception, ce qui serait contre-productif alors? La réponse est simple, vous pouvez attacher plus de politiques à votre rôle Lambda. Par exemple, vous pouvez ajouter la permission d'envoyer des messages à une file différente, dans les lignes :

{
   "Version": "2012-10-17",
   "Statement": [
       {
           "Effect": "Allow",
           "Action": [
               "sqs:ChangeMessageVisibility",
               "sqs:DeleteMessage",
               "sqs:GetQueueAttributes",
               "sqs:ReceiveMessage"
           ],
           "Resource": "ARN_DE_LA_FILE_POUR_LIRE_LES_MESSAGES"
       },
       {
           "Effect": "Allow",
           "Action": [
               "sqs:SendMessage"
           ],
           "Resource": "ARN_DE_LA_FILE_VERS_LAQUELLE_ENVOYER_LES_MESSAGES"
       }
}

Limitez toujours les actions autorisées par votre politique et les ressources au minimum nécessaire. Vous éviterez d'avoir des problèmes à l'avenir lors du passage de votre application à la production.

Conclusion

Nous avons vu comment construire des architectures sans serveur robustes et efficaces dans le cloud en utilisant des fonctions Lambda, le service SQS, les fonctions de pas et un paramétrage restrictif des permissions.

Pour les charges de travail qui sont irrégulières ou ont de longues périodes d'inactivité, cela offre une alternative rentable et facile à gérer par rapport au déploiement de morceaux de code monolithiques dans des machines virtuelles.

Dans cet article, nous nous sommes concentrés sur l'environnement AWS pour l'illustration, mais ces commentaires se traduisent directement vers d'autres fournisseurs de services cloud comme MS Azure (voir article: description d'un cas d'utilisation) ou Google Cloud.

Prêt à atteindre vos objectifs avec les données ?

Si vous souhaitez atteindre vos objectifs grâce à une utilisation plus intelligente des données et de l'IA, vous êtes au bon endroit.

Prêt à atteindre vos objectifs avec les données ?

Si vous souhaitez atteindre vos objectifs grâce à une utilisation plus intelligente des données et de l'IA, vous êtes au bon endroit.

Prêt à atteindre vos objectifs avec les données ?

Si vous souhaitez atteindre vos objectifs grâce à une utilisation plus intelligente des données et de l'IA, vous êtes au bon endroit.

Prêt à atteindre vos objectifs avec les données ?

Si vous souhaitez atteindre vos objectifs grâce à une utilisation plus intelligente des données et de l'IA, vous êtes au bon endroit.

© 2025 Agilytic

© 2025 Agilytic

© 2025 Agilytic