EventBridge로 주문 이벤트 라우팅

AWSBeginner
지금 연습하기

소개

주문 이행에는 새로 접수된 주문이 필요하며 청구와 취소 이벤트는 다른 곳에서 처리합니다. 일치하는 이벤트를 대기열로 라우팅하고 실제로 도착한 메시지를 검증합니다.

SQS로 작업 전송 및 소비와 리소스 정책으로 버킷 보호하기를 먼저 완료하세요. 이 독립적인 VM에는 자체 CLI 접근과 참조 데이터가 제공됩니다. 이전 대기열과 자격 증명은 재사용하지 않습니다.

인증 시험 관련 주제

이 실습은 다음 시험 주제에 대한 실습 경험을 제공합니다.

버스와 대상 대기열 준비

이 단계에서는 이벤트가 들어오는 곳과 일치하는 작업이 소비자를 기다리는 곳을 독립적으로 만듭니다.

Terminal 옆에서 AWS View를 사용하여 CLI 쿼리를 이 실습의 실제 리소스 및 결과와 비교하세요. 제공된 참조 데이터를 유지하세요.

Amazon EventBridge는 발생한 일을 설명하는 이벤트를 라우팅합니다. 버스는 이벤트를 받고 규칙은 필드를 일치시키며 대상은 일치하는 이벤트를 받습니다. 사용자 지정 버스는 이 애플리케이션의 이벤트를 기본 버스와 분리합니다. SQS 대기열은 소비자가 처리할 때까지 전달을 보관합니다. 프로젝트 디렉터리에서 시작하세요. 셸 할당은 CLI가 반환한 식별자를 저장합니다. --query는 필요한 필드를 선택하고 --output text는 다음 명령에서 사용할 수 있게 합니다.

cd /home/labex/project
BUS_NAME=labex-ev01-bus
RULE_NAME=labex-ev01-orders
aws events create-event-bus --name "$BUS_NAME"
QUEUE_URL=$(aws sqs create-queue \
  --queue-name labex-ev01-jobs \
  --query QueueUrl \
  --output text)
QUEUE_ARN=$(aws sqs get-queue-attributes \
  --queue-url "$QUEUE_URL" \
  --attribute-names QueueArn \
  --query Attributes.QueueArn \
  --output text)

버스 응답에는 ARN이 포함되고 QUEUE_URL은 메시지 작업에서 대기열을 식별합니다. 대기열 ARN은 대상이나 권한 정책에서 이를 식별합니다. 이 식별자들은 서로 다른 목적을 갖습니다.

두 빈 리소스를 확인하세요.

aws events list-rules --event-bus-name "$BUS_NAME"
aws sqs get-queue-attributes \
  --queue-url "$QUEUE_URL" \
  --attribute-names ApproximateNumberOfMessages ApproximateNumberOfMessagesNotVisible

아직 규칙이 없으며 대기열에는 사용 가능한 메시지나 처리 중인 메시지가 없습니다. AWS View는 사용자 지정 버스와 빈 대기열을 보여 줍니다. 준비 검사를 실행하세요.

주문 일치 및 규칙 하나에 권한 부여

이 단계에서는 일치하는 규칙을 대기열에 연결하고 해당 규칙의 전달만 허용합니다.

생산자, 버스, 규칙과 대기열

일치하는 규칙은 이벤트를 선택하며 대기열의 소스 규칙 권한은 별도로 전달을 허용합니다.

이벤트 패턴은 이벤트 필드에 대한 필터입니다. source는 생산자를 지정하고 detail-type은 이벤트 범주를 지정합니다. 아래의 각 배열은 허용되는 값을 나열합니다. here-document는 JSON 구분자 사이의 리터럴 JSON을 씁니다. 구분자를 따옴표로 감싸면 셸 확장을 방지합니다. file://는 CLI가 해당 파일을 읽도록 합니다.

cat > order-pattern.json <<'JSON'
{"source":["labex.orders"],"detail-type":["OrderPlaced"]}
JSON
RULE_ARN=$(aws events put-rule \
  --name "$RULE_NAME" \
  --event-bus-name "$BUS_NAME" \
  --event-pattern file://order-pattern.json \
  --state ENABLED \
  --query RuleArn \
  --output text)

규칙은 활성화되었지만 일치하는 것만으로 전달이 허용되지는 않습니다. 대기열 리소스 정책은 EventBridge 서비스의 전송을 허용하고 aws:SourceArn으로 범위를 이 규칙에 제한해야 합니다. 일반 JSON 정책을 작성하세요. 셸이 대기열과 규칙 ARN을 넣습니다.

cat > queue-policy.json <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "events.amazonaws.com"
      },
      "Action": "sqs:SendMessage",
      "Resource": "$QUEUE_ARN",
      "Condition": {
        "ArnEquals": {
          "aws:SourceArn": "$RULE_ARN"
        }
      }
    }
  ]
}
EOF
jq -n --rawfile policy queue-policy.json '{Policy:$policy}' > queue-attributes.json
aws sqs set-queue-attributes \
  --queue-url "$QUEUE_URL" \
  --attributes file://queue-attributes.json

속성 API는 정책을 JSON 문자열로 저장하므로 --rawfile은 해당 문서를 Policy 속성으로 읽습니다. 권한은 대기열 하나와 이를 보내는 규칙 하나를 포함합니다.

대상은 규칙의 목적지입니다. ID를 사용하여 나중에 연결을 업데이트하거나 제거할 수 있습니다.

cat > targets.json <<EOF
[
  {
    "Id": "order-queue",
    "Arn": "$QUEUE_ARN"
  }
]
EOF
aws events put-targets \
  --rule "$RULE_NAME" \
  --event-bus-name "$BUS_NAME" \
  --targets file://targets.json
aws events describe-rule --name "$RULE_NAME" --event-bus-name "$BUS_NAME"
aws events list-targets-by-rule --rule "$RULE_NAME" --event-bus-name "$BUS_NAME"

대상 설정의 FailedEntryCount는 0이고 조회한 규칙에는 의도한 패턴이 있으며 대상 ARN은 본인의 대기열과 같습니다. 이제 AWS View에는 규칙과 대기열 대상이 표시됩니다. 아직 전달할 이벤트는 없습니다. 연결 검사를 실행하세요.

일치와 전달 경계 증명

이 단계에서는 일치하는 이벤트와 관련 없는 이벤트를 게시한 다음 새 대기열 메시지를 추가하지 않고 소스 권한 실패를 테스트합니다.

EventBridge 이벤트에는 라우팅 필드와 detail 페이로드가 있습니다. PutEvents API는 Detail을 JSON으로 인코딩된 문자열로 받습니다. 읽기 쉬운 항목 세 개를 작성하세요. 접수된 주문 하나, 청구 이벤트 하나와 취소 하나입니다. jq는 각 Detail 객체를 API에 필요한 문자열로 변환합니다.

cat > event-inputs.json <<EOF
[
  {
    "EventBusName": "$BUS_NAME",
    "Source": "labex.orders",
    "DetailType": "OrderPlaced",
    "Detail": {
      "id": "route-order",
      "quantity": 2
    }
  },
  {
    "EventBusName": "$BUS_NAME",
    "Source": "labex.billing",
    "DetailType": "OrderPlaced",
    "Detail": {
      "id": "billing-event",
      "quantity": 9
    }
  },
  {
    "EventBusName": "$BUS_NAME",
    "Source": "labex.orders",
    "DetailType": "OrderCancelled",
    "Detail": {
      "id": "cancelled-event",
      "quantity": 1
    }
  }
]
EOF
jq 'map(.Detail |= tojson)' event-inputs.json > events.json
aws events put-events --entries file://events.json
aws sqs get-queue-attributes \
  --queue-url "$QUEUE_URL" \
  --attribute-names ApproximateNumberOfMessages ApproximateNumberOfMessagesNotVisible

게시 응답은 실패한 항목이 0이며 접수된 각 항목의 이벤트 ID를 보고합니다. route-order만 두 필드 모두와 일치하므로 대기열에는 사용 가능한 메시지 하나가 있습니다. AWS View는 소스, 세부 유형, 계정, 리전과 detail을 포함하는 전체 이벤트 봉투를 보여 줍니다.

소비자에게 보이는 실제 본문을 읽으세요. 수신은 일반적으로 표시 제한 시간 동안 메시지를 숨깁니다. --visibility-timeout 0은 확인한 메시지를 즉시 다시 표시합니다. 쿼리는 ID와 본문만 출력하여 수신 핸들이 표시되지 않도록 합니다. 이 확인은 비즈니스 처리를 완료하거나 메시지를 확인 처리하지 않습니다.

fromjson은 SQS 메시지 ID를 유지하면서 각 JSON 본문을 읽기 쉽게 만듭니다. 표시되는 출력만 변경합니다.

aws sqs receive-message \
  --queue-url "$QUEUE_URL" \
  --max-number-of-messages 10 \
  --visibility-timeout 0 \
  --output json | jq '[.Messages[] | {MessageId, Body: (.Body | fromjson)}]'

본문의 detail.id는 route-order이고 detail.quantity는 2입니다. 청구와 취소 항목은 이 대기열에 도달하지 않았습니다.

아래 예시는 활성화된 일치 규칙, 대기열 대상과 계정 및 리전을 포함하는 실제 전체 주문 이벤트를 보여 줍니다.

AWS View의 대상 대기열에 표시된 일치하는 주문 이벤트

이제 규칙과 대상을 활성화된 채 유지하면서 대기열 정책이 다른 소스 ARN을 가리키도록 하세요.

jq --arg wrong "${RULE_ARN}-other" '.Statement[0].Condition.ArnEquals["aws:SourceArn"]=$wrong' queue-policy.json > wrong-source-policy.json
jq -n --rawfile policy wrong-source-policy.json '{Policy:$policy}' > wrong-source-attributes.json
aws sqs set-queue-attributes \
  --queue-url "$QUEUE_URL" \
  --attributes file://wrong-source-attributes.json
cat > event-inputs.json <<EOF
[
  {
    "EventBusName": "$BUS_NAME",
    "Source": "labex.orders",
    "DetailType": "OrderPlaced",
    "Detail": {
      "id": "denied-order",
      "quantity": 4
    }
  }
]
EOF
jq 'map(.Detail |= tojson)' event-inputs.json > denied-event.json
aws events put-events --entries file://denied-event.json
aws sqs get-queue-attributes \
  --queue-url "$QUEUE_URL" \
  --attribute-names ApproximateNumberOfMessages ApproximateNumberOfMessagesNotVisible

EventBridge는 이 이벤트를 접수하지만 규칙에는 필요한 대기열 권한이 없습니다. 원래 메시지만 대기열 이벤트로 남으며 denied-order는 없습니다. 파이프라인을 진단할 때 이벤트 접수와 대상 전달을 구별하세요. 이 실습에서는 전달 재시도를 살펴보지 않습니다.

의도한 권한을 복구하고 다시 확인하세요.

aws sqs set-queue-attributes \
  --queue-url "$QUEUE_URL" \
  --attributes file://queue-attributes.json
aws sqs receive-message \
  --queue-url "$QUEUE_URL" \
  --max-number-of-messages 10 \
  --visibility-timeout 0 \
  --output json | jq '[.Messages[] | {MessageId, Body: (.Body | fromjson)}]'

원래의 route-order만 존재합니다. 수정된 정책은 이후 전달을 허용합니다. 이 실습은 앞서 거부된 이벤트의 재시도에 의존하지 않습니다. 라우팅 검사를 실행하세요.

이벤트 파이프라인 제거

이 단계에서는 관련 없는 리소스를 유지하면서 본인의 대상, 규칙, 사용자 지정 버스와 일회용 대기열을 제거합니다.

규칙을 삭제하기 전에 대상을 제거하세요. 다음으로 사용자 지정 버스와 대기열을 삭제하세요. 대기열 삭제는 라우팅 확인을 위해 보관한 테스트 이벤트를 버립니다. 해당 이벤트의 비즈니스 결과를 주장하지는 않았습니다.

aws events remove-targets \
  --rule "$RULE_NAME" \
  --event-bus-name "$BUS_NAME" \
  --ids order-queue
aws events delete-rule --name "$RULE_NAME" --event-bus-name "$BUS_NAME"
aws events delete-event-bus --name "$BUS_NAME"
aws sqs delete-queue --queue-url "$QUEUE_URL"

성공한 읽기 전용 쿼리가 남은 것을 확인합니다.

aws events list-event-buses
aws events list-rules --event-bus-name default
aws sqs list-queues
aws dynamodb scan --table-name labex-ev01-reference --query Items

기본 버스만 남고 해당 규칙 목록은 비어 있으며 대기열 URL은 없고 참조 항목에는 keep unchanged가 있습니다. 인증 오류나 네트워크 오류는 삭제를 증명하지 않습니다. AWS View는 빈 사용자 지정 리소스 목록과 유지된 참조를 보여 줍니다.

만든 일반 파일을 제거하세요.

rm -f event-inputs.json order-pattern.json queue-policy.json queue-attributes.json targets.json events.json wrong-source-policy.json wrong-source-attributes.json denied-event.json

VM을 종료하기 전에 정리 검사를 실행하세요.

요약

사용자 지정 EventBridge 버스를 만들고 주문 접수 이벤트를 일치시키며 정확한 소스 규칙 권한으로 대기열 대상을 연결했습니다. 실제 대기열 본문은 어떤 이벤트가 소비자에게 도달했는지 보여 주었으며 거부된 소스 테스트로 이벤트 접수와 전달을 구별했습니다. 기본 버스와 참조 데이터를 유지하면서 소유한 리소스를 제거했습니다.

다음 단원에서는 이벤트 봉투를 대기열 소비자에게 필요한 더 작은 페이로드로 변환합니다.