Processo de eventos do Amazon ECS - Amazon Elastic Container Service

Processo de eventos do Amazon ECS

O Amazon ECS envia eventos pelo menos uma vez. Isso significa que você pode receber várias cópias de um determinado evento. Além disso, os eventos não podem ser distribuídos para os ouvintes de evento na ordem em que os eventos ocorreram.

Para que os eventos sejam ordenados adequadamente, a seção detail de cada evento contém uma propriedade version. Sempre que um recurso muda de estado, essa version é incrementada. Eventos duplicados têm a mesma version no objeto detail. Caso esteja replicando o estado da tarefa e da instância de contêiner do Amazon ECS com o Eventbridge, você poderá comparar a versão de um recurso relatado pelas APIs do Amazon ECS com a version relatada no Eventbridge para o recurso para verificar se a versão no fluxo de eventos é atual. Os eventos com um número de propriedade da versão mais alto devem ser tratados como ocorridos depois de eventos com números da versão mais baixos.

Exemplo: processar eventos em uma função do AWS Lambda

O exemplo a seguir mostra uma função do Lambda escrita em Python 3.9 que captura os eventos de alteração na tarefa e no estado da instância de contêiner e os salva em uma das duas tabelas do Amazon DynamoDB:

  • ECSCtrInstanceState: armazena o estado mais recente de uma instância de contêiner. A ID da tabela é o valor containerInstanceArn da instância de contêiner.

  • ECSTaskState: armazena o estado mais recente de uma tarefa. A ID da tabela é o valor taskArn da tarefa.

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 )

O exemplo a seguir do Fargate mostra uma função do Lambda gravada em Python 3.9 que captura os eventos de alteração de estado da tarefa e os salva na seguinte tabela do 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 )