Crear un flujo de pedidos de varios pasos

AWSBeginner
Practicar Ahora

Introducción

La preparación de pedidos debe guardar un pedido y después leer su resumen completado. Conectarás estas tareas en un flujo de trabajo y compararás su historial de ejecución con el resultado real de negocio.

Completa primero Leer y escribir en DynamoDB desde Lambda y sus requisitos previos de roles IAM y registro. Esta VM independiente proporciona un procesador y tablas; tú creas el flujo. El enrutamiento EventBridge es una rama separada.

Relación con las certificaciones

Este laboratorio ofrece práctica para los siguientes temas de examen.

Autorizar al flujo para invocar su procesador

En este paso, inspecciona el procesador de negocio proporcionado y crea un rol de ejecución separado para Step Functions.

permisos del flujo y del procesador

El rol del flujo invoca la función. El rol separado de Lambda realiza las operaciones de tabla.

Usa AWS View junto a Terminal para comparar las consultas CLI con los recursos y resultados reales de este laboratorio. Conserva los datos de referencia proporcionados.

Un flujo de trabajo conecta tareas y decisiones. Una máquina de estados define esos estados; una ejecución ejecuta la definición con una entrada concreta. Esta VM nueva proporciona una función de procesamiento y tablas independientes de pedidos, diagnóstico y referencia. Todavía no hay ninguna máquina de estados ni rol de flujo. El procesador acepta un pedido, escribe su cantidad y total y puede leer su resumen después. Su rol de ejecución Lambda ya autoriza esas operaciones de tabla independientes.

Empieza en el directorio del proyecto. Las asignaciones de shell guardan identificadores devueltos; --query selecciona un campo de respuesta y --output text produce una cadena reutilizable.

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

El procesador usa Python3.12 y su propio rol Lambda; la lista de máquinas está vacía. Step Functions necesita su propio rol de ejecución. Una política de confianza permite al servicio Step Functions asumir ese rol; una política de permisos permite a la sesión resultante invocar exactamente este procesador. Un documento de entrada entre comillas escribe JSON literal y file:// lo lee en la solicitud.

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)

Escribe un documento ordinario de permisos. El shell inserta $WORKER_ARN, limitando este permiso al procesador proporcionado.

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 política tiene un ARN exacto de función. Step Functions no recibe los permisos DynamoDB del procesador: este realiza esas llamadas usando su rol Lambda separado. Ejecuta la comprobación de autorización.

Definir decisiones y dos tareas reales

En este paso, define un flujo de pedidos que valide la cantidad, almacene el pedido y lea su resumen real.

entrada, resultado guardado y resumen

StoreOrder guarda su carga útil real en saved.result; ReadSummary selecciona ese ID de pedido y lee el resumen completado.

Amazon States Language (ASL) es una definición JSON de máquina de estados. StartAt elige el primer estado. Un Choice sigue una rama cuando coincide su condición y, en caso contrario, sigue Default. Un Task invoca un servicio. Next conecta estados; End: true termina correctamente, mientras Fail termina con un error.

La integración optimizada de tareas Lambda usa arn:aws:states:::lambda:invoke. Parameters proporciona argumentos de la función: una clave que termina en .$ evalúa una ruta JSONPath y $ selecciona la entrada actual completa. La integración Lambda devuelve metadatos y Payload. ResultSelector conserva únicamente esa carga útil, ResultPath la inserta en saved conservando la entrada original del pedido y la siguiente tarea selecciona el ID de pedido guardado. Su OutputPath devuelve únicamente la carga útil real del resumen.

Escribe la definición literal y después sustituye su marcador de procesador usando 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 respuesta indica la máquina y su rol de flujo, y la definición indica el procesador proporcionado en ambas tareas. Todavía no se ha procesado ningún pedido. Haz clic en AWS View junto a Terminal para ver la definición real de la máquina y las listas vacías de ejecuciones y pedidos. Ejecuta la comprobación de definición.

Verificar resultados de negocio y una ejecución denegada

En este paso, ejecuta un pedido válido, una cantidad no válida y una ejecución sin permiso de invocación.

start-execution inicia trabajo asíncrono y devuelve un ARN de ejecución. El siguiente bucle de shell con límite lee su estado cada dos segundos hasta que deja de estar en ejecución. $(...) captura la salida del comando, seq proporciona el número de iteraciones y break sale del bucle cuando se cumple la condición. Si sigue RUNNING después del bucle, inspecciona el servicio antes de continuar.

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

Ejemplo oficial de lista de ejecuciones en la consola de Step Functions

La consola oficial enumera nombres y estados de ejecuciones junto con sus tiempos. Sus nombres y flujo difieren de la máquina Standard de este laboratorio. Compara tu estado CLI con el historial y los datos almacenados; usa AWS View para los resultados de este laboratorio.

Fuente: AWS Step Functions.

El estado es SUCCEEDED y la salida contiene el ID de pedido, total_cents:850 y completed:true. El elemento real DynamoDB tiene cantidad 3 y total 850. El historial contiene dos eventos TaskSucceeded: almacenar el pedido y leer su resumen. Un estado de ejecución por sí solo no demuestra un resultado de negocio; compara ambos.

Prueba la rama Choice con cantidad cero:

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

El estado es FAILED con OrderRejected y no hay ningún elemento invalid-order. Choice lo rechazó antes de invocar el procesador.

Ahora elimina únicamente la política Invoke del flujo. El rol del procesador y sus permisos de datos siguen separados. Tu operador todavía puede iniciar una ejecución, pero el rol del flujo no puede invocar su tarea:

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

La ejecución denegada falla en la invocación con un error de acceso denegado; no crea ningún pedido ni realiza ninguna tarea del procesador. Se restablece la política prevista. AWS View muestra el resumen real correcto y ambos fallos junto al único pedido almacenado.

El siguiente ejemplo muestra el resumen real correcto, las ejecuciones rechazadas y el único pedido de negocio.

AWS View muestra el resumen real del flujo y las ejecuciones fallidas

Ejecuta la comprobación de ejecución.

Eliminar los recursos del flujo y los resultados sintéticos

En este paso, elimina tu máquina completada, el rol del flujo, el pedido y los registros, conservando los recursos preparados proporcionados.

Las tres ejecuciones han terminado. Eliminar la máquina la retira de la lista de máquinas activas. Elimina la política del rol propio antes de eliminar el rol y después elimina el pedido sintético y el grupo de registros del procesador creados por tu ejecución.

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

Lee inventarios correctos para demostrar qué permanece:

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

No hay máquinas activas, pedidos ni grupos de registros. Solo permanece el rol del procesador proporcionado y el elemento de referencia está sin cambios. Conserva el procesador y las tablas proporcionados: la responsabilidad de sus recursos preparados difiere de la de los recursos y el flujo que creaste. Los errores de red o autenticación nunca demuestran la eliminación.

Elimina los archivos ordinarios creados en este laboratorio:

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

AWS View muestra máquinas, ejecuciones y pedidos vacíos y la referencia conservada. Ejecuta la comprobación de limpieza antes de finalizar la VM.

Resumen

Creaste un rol de ejecución de flujo con permisos limitados, conectaste Choice y dos tareas Lambda reales, pasaste resultados reales a la siguiente tarea y comparaste el historial de ejecución con los datos de negocio. La entrada no válida y la falta de permiso de invocación no produjeron ningún pedido. Eliminaste los recursos propios del flujo y los resultados sintéticos, conservando los recursos preparados proporcionados.

La siguiente unidad añade reintentos para fallos temporales y tratamiento explícito de errores permanentes.