Repita uma Etapa com Falha e Trate Erros Permanentes

AWSBeginner
Pratique Agora

Introdução

Uma falha temporária de uma dependência pode ser recuperada, enquanto um pedido inválido deve continuar com falha. Você configurará novas tentativas seletivas e um caminho de falha permanente e, depois, observará as tentativas reais e os resultados armazenados.

O Step Functions coordena tarefas Lambda; o worker fornecido grava pedidos no DynamoDB e lê seus resumos. O acesso pela CLI já está configurado; não é necessário ter conta pessoal da AWS nem chaves de acesso.

Conclua primeiro Construa um Fluxo de Pedidos com Várias Etapas. Esta VM nova fornece sua própria função de processamento e tabelas vazias; máquinas, funções IAM e execuções anteriores não são reutilizadas.

Relação com as certificações

Certificação Tarefa do exame Prática
Solutions Architect – Associate (SAA-C03) Tarefa 2.1 Tratamento de erros de fluxos, novas tentativas limitadas e resultados de falha.
Developer – Associate (DVA-C02) Tarefa 1.1 Tratamento de erros de fluxos, novas tentativas limitadas e resultados de falha.
DevOps Engineer – Professional (DOP-C02) Tarefa 5.1 Prática dos fundamentos: Tratamento de erros de fluxos, novas tentativas limitadas e resultados de falha.
Solutions Architect – Professional (SAP-C02) Tarefa 2.4 Prática dos fundamentos: Tratamento de erros de fluxos, novas tentativas limitadas e resultados de falha.

Visão geral do laboratório

Diagrama conceitual: o Step Functions invoca um worker Lambda que lê e grava no DynamoDB; um erro temporário pode ser recuperado por tentativas limitadas, enquanto um erro permanente segue Catch para uma falha explícita.

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.

Use AWS View na parte superior para comparar as consultas da CLI com os recursos e resultados reais deste laboratório. Preserve os dados de referência fornecidos.

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. Para testes sintéticos de falhas, o modo flaky gera TransientOrderError na primeira tentativa, antes de qualquer gravação de negócio; o modo permanent gera InvalidOrder antes de gravar. Tentativas de diagnóstico são separadas dos pedidos de negócio. Sua função de execução Lambda já autoriza essas operações nas tabelas, separadas da 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-ev04-worker

Salve o valor retornado em WORKER_ARN:

WORKER_ARN=$(aws lambda get-function-configuration \
  --function-name labex-ev04-worker \
  --query FunctionArn \
  --output text)
echo "$WORKER_ARN"

Confira o papel e a configuração de ambiente da função:

aws lambda get-function-configuration \
  --function-name labex-ev04-worker \
  --query '{Name:FunctionName,Role:Role,Runtime:Runtime,Timeout:Timeout}'

Confira as máquinas de estados restantes:

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

Salve o valor retornado em ROLE_ARN:

ROLE_ARN=$(aws iam create-role \
  --role-name labex-ev04-workflow-role \
  --assume-role-policy-document file://workflow-trust.json \
  --query Role.Arn \
  --output text)
echo "$ROLE_ARN"

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

Aplique a política de permissões do papel da aplicação:

aws iam put-role-policy \
  --role-name labex-ev04-workflow-role \
  --policy-name InvokeWorker \
  --policy-document file://workflow-invoke.json

Confira a política de permissões do papel da aplicação:

aws iam get-role-policy --role-name labex-ev04-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.

Configure Novas Tentativas Limitadas e um Caminho de Falha Permanente

Nesta etapa, construa um fluxo real de duas tarefas com comportamento seletivo de recuperação.

Nova tentativa temporária e falha permanente — O erro temporário desta função de processamento pode ser recuperado em uma nova tentativa. Seu erro permanente segue Catch até um resultado explicitamente com falha.

O Retry da ASL lista quais erros de tarefas podem ter novas tentativas. ErrorEquals deve corresponder ao tipo de erro da função. IntervalSeconds:1 começa com uma espera de um segundo; BackoffRate:2 multiplica a próxima espera. MaxAttempts:2 permite até duas novas tentativas após a tentativa inicial. Esse retry trata apenas TransientOrderError, não todas as falhas possíveis.

Catch seleciona outro estado para um erro do qual a tarefa não se recuperou. ResultPath registra o erro em failure; Next chega a um estado Fail explícito. Tratar um erro não significa que a tarefa de negócio foi bem-sucedida. Um InvalidOrder permanente termina FAILED com OrderRejected, em vez de fingir que concluiu um pedido.

Um here-document com marcador entre aspas grava JSON literal. O Choice existente rejeita quantidade não positiva; as duas Tasks armazenam o pedido e depois leem o resumo. Payload.$ passa a entrada atual, ResultSelector mantém o conteúdo real da função, ResultPath o preserva em saved e OutputPath retorna o resumo real.

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",
      "Retry": [
        {
          "ErrorEquals": [
            "TransientOrderError"
          ],
          "IntervalSeconds": 1,
          "BackoffRate": 2,
          "MaxAttempts": 2
        }
      ],
      "Catch": [
        {
          "ErrorEquals": [
            "InvalidOrder"
          ],
          "Next": "Rejected",
          "ResultPath": "$.failure"
        }
      ],
      "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": "Order could not be completed"
    }
  }
}
JSON

Escreva a configuração em workflow.json:

jq --arg worker "$WORKER_NAME" '.States.StoreOrder.Parameters.FunctionName=$worker | .States.ReadSummary.Parameters.FunctionName=$worker' workflow-template.json > workflow.json

Salve o valor retornado em MACHINE_ARN:

MACHINE_ARN=$(aws stepfunctions create-state-machine \
  --name labex-ev04-orders \
  --type STANDARD \
  --role-arn "$ROLE_ARN" \
  --definition file://workflow.json \
  --query stateMachineArn \
  --output text)
echo "$MACHINE_ARN"

Confira a definição e o papel da máquina de estados:

aws stepfunctions describe-state-machine \
  --state-machine-arn "$MACHINE_ARN" \
  --query '{Name:name,Definition:definition}'

A definição contém os blocos seletivos de retry e catch. AWS View mostra a mesma configuração; ainda não há execuções ou pedidos de negócio. Execute a verificação da definição de recuperação.

Observe Resultados Reais de Retry, Catch e Permissões

Nesta etapa, execute uma falha temporária, uma falha permanente e uma invocação negada.

A primeira tentativa flaky da função de processamento atualiza um contador de tentativas de diagnóstico e gera um erro antes de gravar um pedido. Sua próxima tentativa pode ser bem-sucedida. Um laço de shell com limite de iterações lê o status da execução a cada dois segundos até que deixe de estar em execução; $(...) captura a saída e break sai do laço. Se a execução continuar RUNNING após o laço, inspecione-a antes de prosseguir.

Escolha a correção pelo tipo de erro: um erro temporário da função pode justificar outra tentativa, um erro permanente de pedido exige uma falha explícita e uma negação de invocação exige restaurar a permissão restrita. O histórico e as tabelas de pedidos e tentativas mostram se a função executou e gravou dados.

RETRY_ARN=$(aws stepfunctions start-execution \
  --state-machine-arn "$MACHINE_ARN" \
  --name retry-order \
  --input '{"id":"retry-order","quantity":2,"mode":"flaky"}' \
  --query executionArn \
  --output text)
echo "$RETRY_ARN"

Consulte esta execução até ela sair do estado RUNNING:

for attempt in $(seq 1 60); do
  STATUS=$(aws stepfunctions describe-execution \
    --execution-arn "$RETRY_ARN" \
    --query status \
    --output text)
  if test "$STATUS" != RUNNING; then break; fi
  sleep 2
done

Confira o estado, a saída e os erros da execução:

aws stepfunctions describe-execution \
  --execution-arn "$RETRY_ARN" \
  --query '{Status:status,Output:output}'

Confira o histórico real de execução do fluxo:

aws stepfunctions get-execution-history \
  --execution-arn "$RETRY_ARN" \
  --query 'events[?type==`TaskFailed` || type==`TaskSucceeded`].{Type:type,Error:taskFailedEventDetails.error}'

Confira o item realmente armazenado no banco de dados:

aws dynamodb get-item \
  --table-name labex-ev04-orders \
  --key '{"id":{"S":"retry-order"}}' \
  --query Item

Confira o item realmente armazenado no banco de dados:

aws dynamodb get-item \
  --table-name labex-ev04-attempts \
  --key '{"id":{"S":"retry-order"}}' \
  --query Item

O status final é SUCCEEDED com o resumo concluído 2/600. O histórico tem um TaskFailed com TransientOrderError seguido de dois eventos TaskSucceeded: armazenamento bem-sucedido e leitura do resumo. O pedido nativo tem quantidade 2/total 600, e as tentativas de diagnóstico são 2. Uma nova tentativa e uma gravação de negócio são contagens diferentes.

Agora use o modo de falha permanente da função de processamento:

PERMANENT_ARN=$(aws stepfunctions start-execution \
  --state-machine-arn "$MACHINE_ARN" \
  --name permanent-order \
  --input '{"id":"permanent-order","quantity":2,"mode":"permanent"}' \
  --query executionArn \
  --output text)
echo "$PERMANENT_ARN"

Consulte esta execução até ela sair do estado RUNNING:

for attempt in $(seq 1 30); do
  STATUS=$(aws stepfunctions describe-execution \
    --execution-arn "$PERMANENT_ARN" \
    --query status \
    --output text)
  if test "$STATUS" != RUNNING; then break; fi
  sleep 2
done

Confira o estado, a saída e os erros da execução:

aws stepfunctions describe-execution \
  --execution-arn "$PERMANENT_ARN" \
  --query '{Status:status,Error:error}'

Confira o histórico real de execução do fluxo:

aws stepfunctions get-execution-history \
  --execution-arn "$PERMANENT_ARN" \
  --query 'events[?type==`TaskFailed` || type==`FailStateEntered`].{Type:type,Error:taskFailedEventDetails.error,State:stateEnteredEventDetails.name}'

Confira o item realmente armazenado no banco de dados:

aws dynamodb get-item \
  --table-name labex-ev04-orders \
  --key '{"id":{"S":"permanent-order"}}' \
  --query Item

Uma chamada real da função de processamento falha com InvalidOrder; Catch chega a Rejected e a execução termina FAILED com OrderRejected. O retry temporário não corresponde a esse erro permanente. Não há item de negócio permanent-order.

Por fim, remova apenas a concessão de invocação do fluxo. Seu operador pode iniciar execuções, mas a função IAM do fluxo não pode invocar a função de processamento:

aws iam delete-role-policy --role-name labex-ev04-workflow-role --policy-name InvokeWorker

Salve o valor retornado em DENIED_ARN:

DENIED_ARN=$(aws stepfunctions start-execution \
  --state-machine-arn "$MACHINE_ARN" \
  --name denied-order \
  --input '{"id":"denied-order","quantity":2,"mode":"flaky"}' \
  --query executionArn \
  --output text)
echo "$DENIED_ARN"

Consulte esta execução até ela sair do estado RUNNING:

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

Confira o estado, a saída e os erros da execução:

aws stepfunctions describe-execution \
  --execution-arn "$DENIED_ARN" \
  --query '{Status:status,Error:error}'

Confira o item realmente armazenado no banco de dados:

aws dynamodb get-item \
  --table-name labex-ev04-orders \
  --key '{"id":{"S":"denied-order"}}' \
  --query Item

Aplique a política de permissões do papel da aplicação:

aws iam put-role-policy \
  --role-name labex-ev04-workflow-role \
  --policy-name InvokeWorker \
  --policy-document file://workflow-invoke.json

Essa execução com acesso negado falha sem invocar a função de processamento nem criar dados de diagnóstico ou de negócio. Repetir o erro de aplicação especificado não corrige a falta de autorização. A concessão pretendida é restaurada. AWS View mostra o resumo da nova tentativa bem-sucedida e duas falhas ao lado do único pedido.

AWS View mostra o sucesso real da nova tentativa e a falha permanente — O exemplo abaixo mostra o resumo real da nova tentativa, a falha permanente e a execução negada ao lado do pedido salvo.

Execute a verificação da recuperação real.

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"

Exclua apenas a política de permissões do papel da aplicação:

aws iam delete-role-policy --role-name labex-ev04-workflow-role --policy-name InvokeWorker

Exclua apenas o papel de execução do fluxo do exercício:

aws iam delete-role --role-name labex-ev04-workflow-role

Exclua apenas o item realmente armazenado no banco de dados:

aws dynamodb delete-item --table-name labex-ev04-orders --key '{"id":{"S":"retry-order"}}'

Exclua apenas o item realmente armazenado no banco de dados:

aws dynamodb delete-item \
  --table-name labex-ev04-attempts \
  --key '{"id":{"S":"retry-order"}}'

Exclua apenas o grupo de logs da aplicação indicado:

aws logs delete-log-group --log-group-name /aws/lambda/labex-ev04-worker

Leia inventários bem-sucedidos para comprovar o que permanece:

aws stepfunctions list-state-machines

Confira os papéis IAM restantes:

aws iam list-roles --query 'Roles[].RoleName'

Confira os pedidos realmente armazenados:

aws dynamodb scan --table-name labex-ev04-orders --query Items

Confira os grupos de logs restantes:

aws logs describe-log-groups --query logGroups

Confira o registro de referência não relacionado ao exercício:

aws dynamodb scan --table-name labex-ev04-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ê configurou novas tentativas limitadas para uma falha temporária específica e Catch para uma falha permanente explícita. O histórico nativo e os pedidos reais distinguiram tentativas de gravações de negócio; a negação de permissão não produziu efeito na função de processamento ou no negócio. Você removeu os recursos do fluxo que criou e os resultados, preservando os recursos de apoio fornecidos.

A próxima unidade trata uma falha que ocorre após a gravação de negócio, quando uma nova tentativa poderia repetir seu efeito.

Para aprofundar o tema, consulte a documentação da AWS: Retry, recuo e tratamento de erros Catch.