Les nouveautés d’AWS Step Functions et deep dive sur le nouveau Workflow Studio


Les nouveautés d’AWS Step Functions

Pour commencer cet article, il est important de savoir à quoi sert le service AWS Step Functions. Mon collègue Nicolas Guary a fait un super article à ce sujet que je vous recommande (https://blog.ippon.fr/2020/12/18/aws-step-functions/).

Pour le citer et présenter en une phrase ce service : “apparu le 1er décembre 2016, AWS Step Functions est un orchestrateur Serverless de services AWS. Il est en passe de devenir un incontournable pour les architectes Cloud. L’utilisation de Step Functions peut simplifier de manière significative des tâches d’orchestration qui n’étaient pas forcément triviales auparavant. Le service repose sur des machines à états dont les deux composants sont les états, et les transitions entre ces états”.

Comme on le sait tous, l’informatique avance à une vitesse folle et depuis 2020 (date de sortie du premier article), tout un tas de nouveautés ont fait surface sur les Steps Functions, je vais donc dans un premier temps vous les présenter.

Dans un ordre chronologique :

  • Le service s’intègre désormais avec Glue DataBrew qui est un outil visuel de préparation de données qui permet aux utilisateurs de nettoyer et normaliser les données sans écrire de code.
  • La définition des machines à état est désormais possible à l’aide de YAML (possible uniquement en JSON auparavant) pour Visual Studio Code et AWS CloudFormation.
  • Le service s’intègre désormais avec Amazon EMR (Elastic MapReduce qui est une plateforme de Big Data) déployé à l’aide du service EKS (Elastic Kubernetes Service).
  • Un nouvel outil Data Flow Simulator a vu le jour, permettant de simuler le mécanisme de traitement de la donnée durant l'exécution d’une tâche. Cela permet de comprendre assez facilement comment l’on passe de l’input à l’output d’une tâche. Si pour vous ce fonctionnement est obscur, cet outil vaut le détour (1).
  • Intégration avec Amazon EventBridge qui est un bus d’événements serverless très pratique pour créer des architectures basées sur les événements.
  • Importante mise à jour ici avec l’introduction de Workflow Studio, je ne vais pas détailler l’outil ici car c’est le sujet même de l’article, il aura donc une présentation en détail par la suite.
  • Second ajout majeur avec l’intégration d’AWS SDK (Software Development Kit) permettant d'interagir avec les API de plus 200 services AWS (liste des services disponible ici https://docs.aws.amazon.com/step-functions/latest/dg/supported-services-awssdk.html)
  • Ajout de la possibilité d'utiliser un VPC endpoint pour les Workflow Synchrones Express (Synchronous Express Workflows) qui n’était pas disponible avant. Cela permet de déployer sa Step Functions dans un VPC.
  • Ajout de la possibilité de créer une API REST avec API Gateway en utilisant le Workflow Synchrone Express comme back-end à l’aide de l’AWS Cloud Development Kit (CDK).
  • On peut désormais mocker les services AWS intégrés avec une Step Function dans le cadre d’utilisation de Step Functions Local. Cet outil permet de télécharger une version de notre Step Function pour pouvoir la lancer en local dans un objectif de test. On pourra alors lui passer un fichier de configuration avec les réponses que l’on souhaite des services que l’on va mocker.

Copie d’écran de l’outil Data Flow Simulator tiré de la documentation d’AWS

Présentation du  Workflow Studio

Le Workflow Studio est un outil dit de “low-code’ qui va permettre de créer une Step Function à l’aide d’une interface graphique en utilisant du drag and drop. L'entièreté du workflow peut être gérée depuis cette interface, en passant de la gestion des entrées/sorties des tâches, l’intégration avec les différents services d’AWS jusqu’à la gestion des erreurs.

Cette interface se présente comme ceci :

Interface du Workflow Studio

Une fois le workflow créé, on peut récupérer l’ASL (Amazon State Language, le langage d’AWS utilisé pour décrire une Step Function) qui a été généré pour pouvoir ensuite l’intégrer à notre outil d’Infrastructure as code préféré.

Un exemple de l’interface avec des tâches déjà créées :

Interface du workflow studio avec des tâches visibles

Maintenant que l’on a vu à quoi ressemble ce studio, je vous propose d’essayer de créer une Step Function complète à l’aide de cet outil.

Cas pratique

Pour ce cas pratique, nous allons essayer de gérer une partie de la logistique d’un bar qui se veut sans serveur (serveurless pour le jeu de mots). Dans un premier temps, on va s’atteler à la partie service, qui, se fera à l’aide d’un petit train sur rail pour amener les consommations (idée prise d’un bar Rennais qui s'appelle le Cactus).

Le but de notre Step Function sera donc de traiter une commande réalisée par un client. Nous allons donc devoir gérer :

  • La commande unitaire et multiple de boisson(s)
  • La gestion des stocks
  • La gestion des erreurs durant notre workflow
  • Parallélisation de la préparation de la commande

Pour commencer, on va créer notre machine à états sur la page du service AWS Step Function :

alt_text
Interface permettant de créer une machine à états

Sur l’écran qui suit, on va appuyer sur le bouton libellé “suivant” directement. Les valeurs par défauts nous vont parfaitement dans cet exemple.

Le point d’entrée de notre workflow est donc la commande. Le client va utiliser une tablette par exemple pour pouvoir faire sa commande. Notre première action est donc de récupérer et de lancer le traitement de sa commande.

Pour la suite de l’article, on partira du principe que le code des lambda est déjà fait. On va donc pouvoir choisir à gauche sur l’interface du Workflow Studio l’action :

alt_text
Action permettant d'invoquer une lambda

Une fois sélectionné, on va pouvoir le glisser/déposer au milieu de l’écran à la suite du start. On va pouvoir changer le nom de l’état sur l’écran de droite par “recuperer_commande” et renseigner le nom de notre fonction dans le champ “Function name”.

alt_text
Interface permettant de configurer l’appel à une lambda

Une chose à savoir ici, si vous ne trouvez pas votre fonction lambda à l’aide de son nom, vous pouvez copier/coller l’arn de votre lambda dans celui-ci et le tour est joué.

On reproduit la même opération, mais, cette fois-ci, on va nommer l’état “lancer_traitement_commande”. On se retrouve donc dans cette configuration :

alt_text
Premier état du workflow

On peut remarquer que si l’on clique sur le premier état et que l’on descend dans la configuration à droite, le champ “Next State" a été mis à jour automatiquement avec le nom “lancer_traitement_commande”.

Maintenant que l’on a lancé le traitement de la commande, on va s'intéresser à ce qui a été commandé. La suite du traitement va dépendre du nombre de boissons que nous avons commandé. Ca tombe bien, il y a un état qui s'appelle Choice et qui nous permet de faire un choix en fonction de(s) paramètre(s) qu’il a reçu. On va renseigner dans la partie “Output’ les paramètres de la fonction :

alt_text
Gestion du résultat de l'exécution d’une lambda

Grâce à l’action que l’on vient de réaliser, on va récupérer en sortie de notre étape :

  • L’input qu’on lui a passé (dans le champ $.order)
  • Le résultat de la lambda (la lambda retournant un json avec un élément isMultipleOrder qui est un booléen)

Maintenant que l’on a nos paramètres, on va pouvoir ajouter l’étape de choix, pour ceci, ouvrir le menu de gauche et choisir Flow en haut. Vous allez voir apparaître l’état Choice en dessous :

alt_text
Ensemble des outils logiques mis à disposition par AWS pour orchestrer les états

Comme pour l’étape de la lambda, on glisse/dépose et le tour est joué. En cliquant dessus, on va pouvoir modifier son nom par “is_boissons_multiple”, on va ensuite renseigner les règles qui vont permettre de choisir dans quel chemin on se dirige pour la suite.

Voici comment faire une condition très simple :

alt_text
Interface permettant de gérer une condition dans une étape de choix

Rappelez-vous du résultat de notre lambda plus haut. On va pouvoir utiliser ce champ ici. Si notre champ “isMultipleOrder” est égal à “true” alors le prochain état sera “preparer_boisson_parallele” (étape que l’on va créer par la suite).

alt_text
Affichage de notre règle créée auparavant

On pourra laisser la règle par défaut qui correspondra au cas où l’on aurait qu’une seule boisson dans notre commande. L’état suivant associé sera : “preparer_boisson_simple”.

Pour ce qui est du traitement “preparer_boisson_parallèle”, nous allons utiliser une autre étape intéressante : “Parallel”. Encore une fois, le nom résume plutôt bien l'utilité de celle-ci. On va pouvoir orchestrer des étapes en parallèle. Dans notre exemple, on va rester assez simple avec la possibilité de préparer 3 types de boissons en parallèle, une étape “preparer_x_ricard”, une “preparer_x_bière” et pour finir “preparer_x_soda”. Nous voici donc avec la situation suivante :

alt_text
Second état du workflow

Maintenant que nous avons préparé les boissons, il va falloir gérer dans un premier temps le cas où l'on a plus de stock au moment où l'on souhaite préparer cette boisson. Pour ce faire, il faut imaginer qu’au moment de la préparation, la lambda renvoie une erreur de type “OutOfStockError” si le stock n’est pas suffisant pour préparer la commande.

Voici un exemple très simple en python pour avoir une erreur de type “OutOfStockError” :

alt_text
Exemple de code python pour raise une erreur


Avec la puissance des Step Functions, on va pouvoir attraper l’erreur et exécuter une étape spécifique si on la rencontre :

  • Cliquez sur la lambda “preparer_x_ricard” par exemple, et rendez-vous sur le menu “Gestion des erreurs” en haut à droite.
  • Ajoutez un “Catch” avec comme nom d’erreur “OutOfStockError” et en “FallBack state” choisissez “Add a state”. Dans la partie “ResultPath”, mettre “OutOfStockError” aussi.
  • Dans le nouvel état ajouté précédemment, renommer le “notifier_clients_plus_de_stock”.
alt_text
Gestion des erreurs durant l’exécution d’une lambda

Félicitations, vous venez de gérer une erreur lors de l'exécution d’une lambda. En plus de ça, vous avez averti le client qu’il n’y avait plus de stock. On peut donc faire la même chose pour la lambda qui permet de gérer la préparation d’une commande simple.

Pour la suite, il va falloir délivrer la/les boisson(s) au(x) client(s) si jamais on n’a pas eu d’erreur. Sinon, il faut aussi penser à re-commander du stock pour la boisson dont on est en rupture.

Pour la partie livraison de la boisson, rien de plus simple maintenant que vous connaissez par cœur comment orchestrer des lambdas. Il suffit de créer 2 lambdas, une qui se nommera “placer_boisson_sur_train” et enfin une “envoyer_train_vers_client” qui se chargeront de gérer la logistique avec le train pour la livraison vers le client.

Sur la partie commande de stock, à la suite de nos étapes en parallèle, rajouter une étape de choix. Ce choix pourra être basé sur la présence ou non du champ “OutOfStockError” en entrée de l’étape. Ce champ correspondant à l’erreur transmise dans la partie “Catch” précédente.

Si l’erreur est présente, alors on rentre dans une nouvelle étape “lancer_reapprovisionnement” que l’on relie ensuite à l’étape “placer_boisson_sur_train”. Si l’erreur n’est pas présente, on passe directement à l’étape “placer_boisson_sur_train”.

Et voilà, nous avons un workflow complet désormais ! On peut gérer la commande, préparer les boissons, gérer son stock en temps réel et pour finir, livrer les clients à l’aide de notre petit train. Et tout ça sans avoir quasiment écrit une seule ligne de code. Voici ce à quoi ressemble notre workflow final dans le studio :

alt_text
Aperçu final de notre workflow

Pour se rendre compte du temps que l’on à gagné grâce au Workflow Studio, il suffit de regarder le nombre de lignes d’ASL générées : 296. On notera aussi que lors de la génération du code ASL, AWS complète le code des bonnes pratiques. Sur chaque étape en relation avec des lambdas, un bloc de rejeu a été ajouté si jamais les erreurs sont des erreurs du service Lambda avec des valeurs par défaut pour les paramètres de rejeu.

alt_text
Code généré par AWS non spécifié dans le workflow studio

Pour conclure

Pour conclure sur cet outil qu’est le workflow studio et le service AWS Step Functions, c’est un service qui, je pense, sera de plus en plus utilisé. La facilité de création d’un workflow est assez déconcertante. L’intégration facile avec une grosse partie des services AWS est un plus. AWS s’investit encore et toujours sur ce service pour sortir de nouvelles intégrations, des mises à jour de l’interface et pleins d’autres choses.

L’ayant utilisé personnellement dans ma mission, il nous a permis à mon équipe et moi de très facilement construire un workflow composé de Lambdas. En lisant le cahier des charges, le workflow nous paraissait très complexe et difficile à maintenir, car nous aurions dû créer nous-même une sorte d’orchestrateur pour nos fonctions. Le fait d’avoir à disposition une interface super ergonomique pour construire notre workflow et surtout un service permettant de suivre l'exécution de celui-ci lors des tests nous a fait économiser un temps considérable. C’est donc sans aucun regret que nous travaillons aujourd’hui avec ce service.