Construire un workflow de commande en plusieurs étapes

AWSBeginner
Pratiquer maintenant

Introduction

La préparation des commandes doit enregistrer une commande, puis lire son résumé terminé. Vous relierez ces tâches dans un workflow et comparerez son historique d'exécution au résultat métier réel.

Terminez d'abord Lire et écrire dans DynamoDB depuis Lambda et ses prérequis de rôles IAM et de journalisation. Cette VM indépendante fournit un traitement et des tables ; vous créez le workflow. Le routage EventBridge est une branche distincte.

Lien avec les certifications

Ce laboratoire propose une pratique des sujets d’examen suivants.

Autoriser le workflow à invoquer son traitement

Dans cette étape, inspectez le traitement métier fourni et créez un rôle d'exécution distinct pour Step Functions.

Permissions du workflow et du traitement

Le rôle du workflow invoque la fonction. Le rôle Lambda distinct effectue les opérations sur les tables.

Utilisez AWS View à côté de Terminal pour comparer les requêtes CLI avec les ressources et résultats réels de ce laboratoire. Conservez les données de référence fournies.

Un workflow relie des tâches et des décisions. Une machine à états définit ces états ; une exécution applique la définition à une entrée donnée. Cette VM neuve fournit une fonction de traitement et des tables indépendantes de commandes, de diagnostic et de référence. Il n'y a encore ni machine à états ni rôle de workflow. Le traitement accepte une commande, écrit sa quantité et son total et peut ensuite lire son résumé. Son rôle d'exécution Lambda autorise déjà ces opérations distinctes sur les tables.

Commencez dans le répertoire du projet. Les affectations du shell enregistrent les identifiants renvoyés ; --query sélectionne un champ de réponse et --output text produit une chaîne réutilisable.

cd /home/labex/project
WORKER_NAME=labex-ev03-worker
WORKER_ARN=$(aws lambda get-function-configuration \
  --function-name labex-ev03-worker \
  --query FunctionArn \
  --output text)
aws lambda get-function-configuration \
  --function-name labex-ev03-worker \
  --query '{Name:FunctionName,Role:Role,Runtime:Runtime,Timeout:Timeout}'
aws stepfunctions list-state-machines

Le traitement utilise Python3.12 et son propre rôle Lambda ; la liste des machines est vide. Step Functions a besoin de son propre rôle d'exécution. Une politique de confiance permet au service Step Functions d'assumer ce rôle ; une politique de permissions permet à la session résultante d'invoquer exactement ce traitement. Un document intégré avec un marqueur entre guillemets écrit du JSON littéral et file:// le lit dans la requête.

cat > workflow-trust.json <<'JSON'
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "states.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
JSON
ROLE_ARN=$(aws iam create-role \
  --role-name labex-ev03-workflow-role \
  --assume-role-policy-document file://workflow-trust.json \
  --query Role.Arn \
  --output text)

Écrivez un document de permissions ordinaire. Le shell insère $WORKER_ARN, limitant cette autorisation au traitement fourni.

cat > workflow-invoke.json <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "lambda:InvokeFunction",
      "Resource": "$WORKER_ARN"
    }
  ]
}
EOF
aws iam put-role-policy \
  --role-name labex-ev03-workflow-role \
  --policy-name InvokeWorker \
  --policy-document file://workflow-invoke.json
aws iam get-role-policy --role-name labex-ev03-workflow-role --policy-name InvokeWorker

La politique possède un seul ARN exact de fonction. Step Functions ne reçoit pas les permissions DynamoDB du traitement : celui-ci effectue ces appels avec son rôle Lambda distinct. Exécutez la vérification de l'autorisation.

Définir les décisions et deux tâches réelles

Dans cette étape, définissez un workflow de commande qui valide la quantité, stocke la commande et lit son résumé réel.

Entrée, résultat enregistré et résumé

StoreOrder enregistre sa charge utile réelle sous saved.result ; ReadSummary sélectionne cet identifiant de commande et lit le résumé terminé.

Amazon States Language (ASL) est une définition JSON de machine à états. StartAt choisit le premier état. Un Choice suit une branche lorsque sa condition correspond, sinon il suit Default. Un Task invoque un service. Next relie les états ; End: true termine avec succès, tandis que Fail termine avec une erreur.

L'intégration optimisée des tâches Lambda utilise arn:aws:states:::lambda:invoke. Parameters fournit les arguments de la fonction : une clé se terminant par .$ évalue un JSONPath et $ sélectionne l'entrée actuelle complète. L'intégration Lambda renvoie des métadonnées et Payload. ResultSelector conserve uniquement cette charge utile, ResultPath l'insère sous saved en préservant l'entrée d'origine de la commande et la tâche suivante sélectionne l'identifiant de commande enregistré. Son OutputPath renvoie uniquement la charge utile du résumé réel.

Écrivez la définition littérale, puis remplacez son espace réservé de traitement avec jq --arg :

cat > workflow-template.json <<'JSON'
{
  "StartAt": "CheckQuantity",
  "States": {
    "CheckQuantity": {
      "Type": "Choice",
      "Choices": [
        {
          "Variable": "$.quantity",
          "NumericGreaterThan": 0,
          "Next": "StoreOrder"
        }
      ],
      "Default": "Rejected"
    },
    "StoreOrder": {
      "Type": "Task",
      "Resource": "arn:aws:states:::lambda:invoke",
      "Parameters": {
        "FunctionName": "WORKER_NAME",
        "Payload.$": "$"
      },
      "ResultSelector": {
        "result.$": "$.Payload"
      },
      "ResultPath": "$.saved",
      "Next": "ReadSummary"
    },
    "ReadSummary": {
      "Type": "Task",
      "Resource": "arn:aws:states:::lambda:invoke",
      "Parameters": {
        "FunctionName": "WORKER_NAME",
        "Payload": {
          "stage": "summary",
          "id.$": "$.saved.result.id"
        }
      },
      "OutputPath": "$.Payload",
      "End": true
    },
    "Rejected": {
      "Type": "Fail",
      "Error": "OrderRejected",
      "Cause": "Quantity must be positive"
    }
  }
}
JSON
jq --arg worker "$WORKER_NAME" '.States.StoreOrder.Parameters.FunctionName=$worker | .States.ReadSummary.Parameters.FunctionName=$worker' workflow-template.json > workflow.json
MACHINE_ARN=$(aws stepfunctions create-state-machine \
  --name labex-ev03-orders \
  --type STANDARD \
  --role-arn "$ROLE_ARN" \
  --definition file://workflow.json \
  --query stateMachineArn \
  --output text)
aws stepfunctions describe-state-machine \
  --state-machine-arn "$MACHINE_ARN" \
  --query '{Name:name,Role:roleArn,Definition:definition}'

La réponse nomme la machine et son rôle de workflow et la définition nomme le traitement fourni dans les deux tâches. Rien n'a encore traité de commande. Cliquez sur AWS View à côté de Terminal pour voir la définition réelle de la machine et les listes d'exécutions et de commandes vides. Exécutez la vérification de la définition.

Vérifier les résultats métier et une exécution refusée

Dans cette étape, exécutez une commande valide, une quantité invalide et une exécution sans permission d'invocation.

start-execution lance un travail asynchrone et renvoie un ARN d'exécution. La boucle shell limitée suivante lit son statut toutes les deux secondes jusqu'à ce qu'il cesse de fonctionner. $(...) capture la sortie de commande, seq fournit le nombre de passages de la boucle et break quitte la boucle lorsque la condition correspond. Si le statut reste RUNNING après la boucle, inspectez le service avant de continuer.

EXECUTION_ARN=$(aws stepfunctions start-execution \
  --state-machine-arn "$MACHINE_ARN" \
  --name valid-order \
  --input '{"id":"workflow-order","quantity":3}' \
  --query executionArn \
  --output text)
for attempt in $(seq 1 60); do
  STATUS=$(aws stepfunctions describe-execution \
    --execution-arn "$EXECUTION_ARN" \
    --query status \
    --output text)
  if test "$STATUS" != RUNNING; then break; fi
  sleep 2
done
aws stepfunctions describe-execution \
  --execution-arn "$EXECUTION_ARN" \
  --query '{Status:status,Output:output}'
aws stepfunctions get-execution-history \
  --execution-arn "$EXECUTION_ARN" \
  --query 'events[].type'
aws dynamodb get-item \
  --table-name labex-ev03-orders \
  --key '{"id":{"S":"workflow-order"}}' \
  --query Item

Exemple de liste d'exécutions dans la console officielle Step Functions

La console officielle liste les noms et statuts d'exécution avec les informations temporelles. Ses noms et son workflow diffèrent de la machine Standard de ce laboratoire. Comparez votre statut CLI avec l'historique et les données stockées ; utilisez AWS View pour les résultats de ce laboratoire.

Source : AWS Step Functions.

Le statut est SUCCEEDED et la sortie contient l'identifiant de commande, total_cents:850 et completed:true. L'élément DynamoDB réel a une quantité de 3 et un total de 850. L'historique contient deux événements TaskSucceeded : le stockage de la commande et la lecture de son résumé. Un statut d'exécution seul ne prouve pas un résultat métier ; comparez les deux.

Testez la branche Choice avec une quantité de zéro :

INVALID_ARN=$(aws stepfunctions start-execution \
  --state-machine-arn "$MACHINE_ARN" \
  --name invalid-order \
  --input '{"id":"invalid-order","quantity":0}' \
  --query executionArn \
  --output text)
for attempt in $(seq 1 30); do
  STATUS=$(aws stepfunctions describe-execution \
    --execution-arn "$INVALID_ARN" \
    --query status \
    --output text)
  if test "$STATUS" != RUNNING; then break; fi
  sleep 2
done
aws stepfunctions describe-execution \
  --execution-arn "$INVALID_ARN" \
  --query '{Status:status,Error:error}'
aws dynamodb get-item \
  --table-name labex-ev03-orders \
  --key '{"id":{"S":"invalid-order"}}' \
  --query Item

Le statut est FAILED avec OrderRejected et il n'existe aucun élément invalid-order. Choice l'a rejeté avant d'invoquer le traitement.

Retirez maintenant uniquement la politique Invoke du workflow. Le rôle et les permissions de données du traitement restent distincts. Votre opérateur peut toujours démarrer une exécution, mais le rôle du workflow ne peut pas invoquer sa tâche :

aws iam delete-role-policy --role-name labex-ev03-workflow-role --policy-name InvokeWorker
DENIED_ARN=$(aws stepfunctions start-execution \
  --state-machine-arn "$MACHINE_ARN" \
  --name denied-order \
  --input '{"id":"denied-order","quantity":2}' \
  --query executionArn \
  --output text)
for attempt in $(seq 1 30); do
  STATUS=$(aws stepfunctions describe-execution \
    --execution-arn "$DENIED_ARN" \
    --query status \
    --output text)
  if test "$STATUS" != RUNNING; then break; fi
  sleep 2
done
aws stepfunctions describe-execution \
  --execution-arn "$DENIED_ARN" \
  --query '{Status:status,Error:error}'
aws dynamodb get-item \
  --table-name labex-ev03-orders \
  --key '{"id":{"S":"denied-order"}}' \
  --query Item
aws iam put-role-policy \
  --role-name labex-ev03-workflow-role \
  --policy-name InvokeWorker \
  --policy-document file://workflow-invoke.json

L'exécution refusée échoue à l'invocation avec une erreur de refus d'accès ; elle ne crée aucune commande et n'effectue aucune tâche du traitement. La politique prévue est rétablie. AWS View affiche le véritable résumé réussi et les deux échecs à côté de l'unique commande stockée.

L'exemple ci-dessous montre le véritable résumé réussi, les exécutions rejetées et l'unique commande métier.

AWS View affiche le résumé réel du workflow et les exécutions échouées

Exécutez la vérification de l'exécution.

Supprimer les ressources du workflow et les résultats fictifs

Dans cette étape, supprimez votre machine terminée, le rôle du workflow, la commande et les journaux en conservant les ressources de démonstration fournies.

Les trois exécutions sont terminées. Supprimer la machine la retire de la liste des machines actives. Retirez votre politique de rôle avant de supprimer le rôle, puis retirez la commande fictive et le groupe de journaux du traitement créé par votre exécution.

aws stepfunctions delete-state-machine --state-machine-arn "$MACHINE_ARN"
aws iam delete-role-policy --role-name labex-ev03-workflow-role --policy-name InvokeWorker
aws iam delete-role --role-name labex-ev03-workflow-role
aws dynamodb delete-item \
  --table-name labex-ev03-orders \
  --key '{"id":{"S":"workflow-order"}}'
aws dynamodb delete-item \
  --table-name labex-ev03-attempts \
  --key '{"id":{"S":"workflow-order"}}'
aws logs delete-log-group --log-group-name /aws/lambda/labex-ev03-worker

Lisez des inventaires avec succès pour prouver ce qui reste :

aws stepfunctions list-state-machines
aws iam list-roles --query 'Roles[].RoleName'
aws dynamodb scan --table-name labex-ev03-orders --query Items
aws logs describe-log-groups --query logGroups
aws dynamodb scan --table-name labex-ev03-reference --query Items

Il n'y a aucune machine active, commande ni groupe de journaux. Seul le rôle du traitement fourni reste et l'élément de référence est inchangé. Gardez le traitement et les tables fournis : leur appartenance à la préparation diffère de celle du workflow et des ressources que vous avez créés. Les erreurs de réseau ou d'authentification ne prouvent jamais la suppression.

Supprimez les fichiers ordinaires créés dans ce laboratoire :

rm -f workflow-trust.json workflow-invoke.json workflow-template.json workflow.json

AWS View affiche les listes de machines, d'exécutions et de commandes vides et la référence conservée. Exécutez la vérification du nettoyage avant de terminer la VM.

Résumé

Vous avez créé un rôle d'exécution de workflow limité, relié Choice et deux tâches Lambda réelles, transmis les résultats réels à la tâche suivante et comparé l'historique d'exécution aux données métier. Une entrée invalide et une permission d'invocation manquante n'ont produit aucune commande. Vous avez supprimé vos ressources de workflow et les résultats fictifs en conservant les ressources de démonstration fournies.

L'unité suivante ajoute des nouvelles tentatives pour les échecs temporaires et un traitement explicite des erreurs permanentes.