Control de eventos de Amazon ECS - Amazon Elastic Container Service

Control de eventos de Amazon ECS

Amazon ECS envía los eventos siguiendo el criterio al menos una vez. Esto significa que podría recibir varias copias de un evento determinado. Además, los eventos podrían no entregarse a los escuchas de evento en el orden en que ocurrieron los eventos.

Para permitir un orden correcto de eventos, la sección detail de cada evento contiene una propiedad version. Cada vez que un recurso cambia de estado, se incrementa esta version. Los eventos duplicados tienen la misma version en el objeto detail. Si está replicando la instancia de contenedor de Amazon ECS y el estado de tarea con EventBridge, puede comparar la versión de un recurso notificado por las API de Amazon ECS con la version notificada en EventBridge para que el recurso verifique que la versión en su secuencia de eventos sea actual. Los eventos con un número de propiedad de versión más alto se deberían tratar como que han ocurrido más tarde que los eventos con números de versión más bajos.

Ejemplo: Control de eventos en una función de AWS Lambda

El ejemplo siguiente muestra una función de Lambda escrita en Python 3.9 que captura los eventos de cambio de estado de instancia de contenedor y de tarea y los guarda en una de estas dos tablas de Amazon DynamoDB:

  • ECSCtrInstanceState: almacena el estado más reciente de una instancia de contenedor. El ID de tabla es el valor containerInstanceArn de la instancia de contenedor.

  • ECSTaskState almacena el estado más reciente de una tarea. El ID de tabla es el valor taskArn de la tarea.

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 )

El ejemplo siguiente de Fargate muestra una función de Lambda escrita en Python 3.9 que captura los eventos de cambio de estado de tarea y los guarda en la siguiente tabla de 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 )