Amazon ECS 이벤트 처리 - Amazon Elastic Container Service

Amazon ECS 이벤트 처리

Amazon ECS는 이벤트를 한 번 이상 전송합니다. 즉, 지정된 이벤트의 복사본을 여러 개 받을 수 있습니다. 또한 이벤트가 이벤트 발생 순서대로 이벤트 리스너에게 전달되지 않을 수 있습니다.

이벤트 순서가 적절히 지정될 수 있도록 각 이벤트의 detail 섹션에 version 속성이 포함됩니다. 리소스 상태가 변경될 때마다 이 version이 증가합니다. 중복 이벤트는 detail 객체에서 동일한 version을 갖습니다. EventBridge를 사용하여 Amazon ECS 컨테이너 인스턴스 및 작업 상태를 복제하는 경우, Amazon ECS API에서 보고된 리소스 버전과 리소스에 대해 EventBridge에서 보고된 version을 비교하여 이벤트 스트림 버전이 최신임을 확인할 수 있습니다. 버전 속성 번호가 높은 이벤트는 낮은 버전 번호의 이벤트보다 나중에 발생한 것으로 처리해야 합니다.

예제: AWS Lambda 함수에서 이벤트 처리

다음 예제는 Python 3.9로 작성된 Lambda 함수로서, 작업과 컨테이너 인스턴스 상태 변경 이벤트를 모두 캡처하여 두 개의 Amazon DynamoDB 테이블 중 하나에 저장합니다.

  • ECSCtrInstanceState – 컨테이너 인스턴스의 최신 상태를 저장합니다. 테이블 ID는 컨테이너 인스턴스의 containerInstanceArn 값입니다.

  • ECSTaskState – 작업의 최신 상태를 저장합니다. 테이블 ID는 작업의 taskArn 값입니다.

import json import boto3 def lambda_handler(event, context): id_name = "" new_record = {} # For debugging so you can see raw event format. print('Here is the event:') print((json.dumps(event))) if event["source"] != "aws.ecs": raise ValueError("Function only supports input from events with a source type of: aws.ecs") # Switch on task/container events. table_name = "" if event["detail-type"] == "ECS Task State Change": table_name = "ECSTaskState" id_name = "taskArn" event_id = event["detail"]["taskArn"] elif event["detail-type"] == "ECS Container Instance State Change": table_name = "ECSCtrInstanceState" id_name = "containerInstanceArn" event_id = event["detail"]["containerInstanceArn"] else: raise ValueError("detail-type for event is not a supported type. Exiting without saving event.") new_record["cw_version"] = event["version"] new_record.update(event["detail"]) # "status" is a reserved word in DDB, but it appears in containerPort # state change messages. if "status" in event: new_record["current_status"] = event["status"] new_record.pop("status") # Look first to see if you have received a newer version of an event ID. # If the version is OLDER than what you have on file, do not process it. # Otherwise, update the associated record with this latest information. print("Looking for recent event with same ID...") dynamodb = boto3.resource("dynamodb", region_name="us-east-1") table = dynamodb.Table(table_name) saved_event = table.get_item( Key={ id_name : event_id } ) if "Item" in saved_event: # Compare events and reconcile. print(("EXISTING EVENT DETECTED: Id " + event_id + " - reconciling")) if saved_event["Item"]["version"] < event["detail"]["version"]: print("Received event is a more recent version than the stored event - updating") table.put_item( Item=new_record ) else: print("Received event is an older version than the stored event - ignoring") else: print(("Saving new event - ID " + event_id)) table.put_item( Item=new_record )

다음 Fargate 예제는 Python 3.9로 작성된 Lambda 함수로, 작업 상태 변경 이벤트를 캡처하여 다음 Amazon DynamoDB 테이블에 저장합니다.

import json import boto3 def lambda_handler(event, context): id_name = "" new_record = {} # For debugging so you can see raw event format. print('Here is the event:') print((json.dumps(event))) if event["source"] != "aws.ecs": raise ValueError("Function only supports input from events with a source type of: aws.ecs") # Switch on task/container events. table_name = "" if event["detail-type"] == "ECS Task State Change": table_name = "ECSTaskState" id_name = "taskArn" event_id = event["detail"]["taskArn"] else: raise ValueError("detail-type for event is not a supported type. Exiting without saving event.") new_record["cw_version"] = event["version"] new_record.update(event["detail"]) # "status" is a reserved word in DDB, but it appears in containerPort # state change messages. if "status" in event: new_record["current_status"] = event["status"] new_record.pop("status") # Look first to see if you have received a newer version of an event ID. # If the version is OLDER than what you have on file, do not process it. # Otherwise, update the associated record with this latest information. print("Looking for recent event with same ID...") dynamodb = boto3.resource("dynamodb", region_name="us-east-1") table = dynamodb.Table(table_name) saved_event = table.get_item( Key={ id_name : event_id } ) if "Item" in saved_event: # Compare events and reconcile. print(("EXISTING EVENT DETECTED: Id " + event_id + " - reconciling")) if saved_event["Item"]["version"] < event["detail"]["version"]: print("Received event is a more recent version than the stored event - updating") table.put_item( Item=new_record ) else: print("Received event is an older version than the stored event - ignoring") else: print(("Saving new event - ID " + event_id)) table.put_item( Item=new_record )