Construa um Fluxo de Pedidos com Várias Etapas

AWSBeginner
Pratique Agora

Introdução

O atendimento de pedidos deve salvar um pedido e depois ler seu resumo concluído. Você conectará essas tarefas em um fluxo de trabalho e comparará seu histórico de execução com o resultado real de negócio.

Conclua primeiro Leia e Grave no DynamoDB a partir do Lambda e seus pré-requisitos de funções IAM e logs. Esta VM independente fornece um consumidor e tabelas; você cria o fluxo. O roteamento com EventBridge é um ramo separado.

Relação com as certificações

Este laboratório oferece prática nos seguintes tópicos de exame.

Autorize o Fluxo a Invocar Sua Função de Processamento

Nesta etapa, inspecione a função de processamento de negócio fornecida e crie uma função de execução separada para o Step Functions.

Permissões do fluxo e da função de processamento

A função IAM do fluxo invoca a função Lambda. A função IAM separada do Lambda realiza as operações nas tabelas.

Use AWS View ao lado do Terminal para comparar as consultas da CLI com os recursos e resultados reais deste laboratório. Preserve os dados de referência fornecidos.

Um fluxo de trabalho conecta tarefas e decisões. Uma máquina de estados define esses estados; uma execução executa a definição com uma entrada específica. Esta VM nova fornece uma função de processamento e tabelas independentes de pedidos, diagnóstico e referência. Ainda não há máquina de estados nem função IAM do fluxo. A função de processamento aceita um pedido, grava sua quantidade e seu total e pode ler seu resumo depois. Sua função de execução Lambda já autoriza essas operações nas tabelas, que são separadas do trabalho de configuração do fluxo.

Comece no diretório do projeto. Atribuições no shell salvam identificadores retornados; --query seleciona um campo da resposta e --output text produz uma string reutilizável.

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

A função de processamento usa Python3.12 e sua própria função IAM Lambda; a lista de máquinas está vazia. O Step Functions precisa de sua própria função de execução. Uma política de confiança permite que o serviço Step Functions assuma essa função IAM; uma política de permissões permite que a sessão resultante invoque exatamente esta função de processamento. Um here-document com marcador entre aspas grava JSON literal, e file:// o lê na solicitação.

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)

Escreva um documento comum de permissões. O shell insere $WORKER_ARN, limitando essa concessão à função de processamento fornecida.

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

A política tem um único ARN exato de função. O Step Functions não recebe as permissões DynamoDB da função de processamento: ela realiza essas chamadas usando sua função IAM Lambda separada. Execute a verificação da autorização.

Defina Decisões e Duas Tarefas Reais

Nesta etapa, defina um fluxo de pedidos que valide a quantidade, armazene o pedido e leia seu resumo real.

Entrada, resultado salvo e resumo

StoreOrder salva seu conteúdo real em saved.result; ReadSummary seleciona esse ID de pedido e lê o resumo concluído.

A Amazon States Language (ASL) é uma definição de máquina de estados em JSON. StartAt escolhe o primeiro estado. Um Choice segue um ramo quando sua condição corresponde e, caso contrário, segue Default. Uma Task invoca um serviço. Next conecta estados; End: true termina com sucesso, enquanto Fail termina com um erro.

A integração otimizada de tarefas Lambda usa arn:aws:states:::lambda:invoke. Parameters fornece os argumentos da função: uma chave terminada em .$ avalia um JSONPath, e $ seleciona toda a entrada atual. A integração Lambda retorna metadados mais Payload. ResultSelector mantém apenas esse conteúdo, ResultPath o insere em saved, preservando a entrada original do pedido, e a próxima tarefa seleciona o ID do pedido salvo. Seu OutputPath retorna apenas o conteúdo real do resumo.

Escreva a definição literal e depois substitua seu marcador da função de processamento 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}'

A resposta nomeia a máquina e sua função IAM do fluxo, e a definição nomeia a função de processamento fornecida nas duas tarefas. Nada processou um pedido ainda. Clique em AWS View ao lado do Terminal para ver a definição real da máquina e as listas vazias de execuções e pedidos. Execute a verificação da definição.

Verifique Resultados de Negócio e uma Execução Negada

Nesta etapa, execute um pedido válido, uma quantidade inválida e uma execução sem permissão de invocação.

start-execution inicia trabalho assíncrono e retorna um ARN de execução. O laço de shell com limite de iterações a seguir lê seu status a cada dois segundos até que deixe de estar em execução. $(...) captura a saída do comando, seq fornece a contagem do laço e break sai do laço quando a condição corresponde. Se continuar RUNNING após o laço, inspecione o serviço antes de prosseguir.

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

Exemplo oficial da lista de execuções no Console do Step Functions

O Console oficial lista nomes e status de execuções junto com informações de tempo. Seus nomes e fluxo diferem da máquina Standard deste laboratório. Compare seu status na CLI com o histórico e os dados armazenados; use AWS View para os resultados deste laboratório.

Fonte: AWS Step Functions.

O status é SUCCEEDED, e a saída contém o ID do pedido, total_cents:850 e completed:true. O item real no DynamoDB tem quantidade 3 e total 850. O histórico contém dois eventos TaskSucceeded: o armazenamento do pedido e a leitura de seu resumo. Um status de execução, por si só, não comprova um resultado de negócio; compare ambos.

Teste o ramo Choice com quantidade zero:

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

O status é FAILED com OrderRejected, e não há item invalid-order. Choice o rejeitou antes de invocar a função de processamento.

Agora remova apenas a política Invoke do fluxo. A função IAM da função de processamento e suas permissões de dados continuam separadas. Iniciar uma execução ainda é permitido para seu operador, mas a função IAM do fluxo não pode invocar sua tarefa:

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

A execução negada falha na invocação com um erro de acesso negado; não cria pedido nem realiza tarefa da função de processamento. A política pretendida é restaurada. AWS View mostra o resumo real bem-sucedido e as duas falhas ao lado do único pedido armazenado.

O exemplo abaixo mostra o resumo real bem-sucedido, as execuções rejeitadas e o único pedido de negócio.

AWS View mostra o resumo real do fluxo e as execuções com falha

Execute a verificação da execução.

Remova os Recursos do Fluxo e os Resultados Sintéticos

Nesta etapa, exclua sua máquina concluída, a função IAM do fluxo, o pedido e os logs, preservando os recursos de apoio fornecidos.

As três execuções terminaram. Excluir a máquina a remove da lista de máquinas ativas. Remova a política da função IAM que você criou antes de excluir essa função IAM e, depois, remova o pedido sintético e o grupo de logs da função de processamento criados por sua execução.

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

Leia inventários bem-sucedidos para comprovar o que 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

Não há máquinas ativas, pedidos ou grupos de logs. Apenas a função IAM fornecida da função de processamento permanece, e o item de referência está inalterado. Mantenha a função de processamento e as tabelas fornecidas: elas foram criadas pela preparação, enquanto o fluxo e seus recursos foram criados por você. Erros de rede ou de autenticação nunca comprovam a exclusão.

Remova os arquivos comuns criados neste laboratório:

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

AWS View mostra máquinas, execuções e pedidos vazios e a referência preservada. Execute a verificação da limpeza antes de encerrar a VM.

Resumo

Você criou uma função de execução do fluxo com permissões restritas, conectou Choice e duas tarefas Lambda reais, passou resultados reais à próxima tarefa e comparou o histórico de execução com os dados de negócio. Entrada inválida e falta de permissão de invocação não produziram pedido. Você removeu os recursos do fluxo que criou e os resultados sintéticos, preservando os recursos de apoio fornecidos.

A próxima unidade adiciona novas tentativas para falhas temporárias e tratamento explícito de erros permanentes.