Gestion des événements Amazon ECS - Amazon Elastic Container Service

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

Gestion des événements Amazon ECS

Amazon ECS envoie des événements au moins une fois. Cela signifie que vous pouvez recevoir plusieurs copies d'un événement donné. En outre, des événements peuvent ne pas être transmis aux écouteurs d'événements dans l'ordre dans lequel ils se produisent.

Pour bien ordonner les événements, la section detail de chaque événement contient une propriété version. Chaque fois qu'une ressource change d'état, cette version est incrémentée. Les événements en double présentent la même version dans l'objet detail. Si vous répliquez votre instance de conteneur Amazon ECS et l'état de votre tâche avec EventBridge, vous pouvez comparer la version d'une ressource signalée par les API Amazon ECS avec celle version signalée EventBridge pour la ressource afin de vérifier que la version de votre flux d'événements est à jour. Les événements avec un numéro de propriétés de version plus élevé doivent être traités comme postérieurs aux événements avec des numéros de version inférieurs.

Exemple : gestion des événements dans une fonction AWS Lambda

L'exemple suivant montre une fonction Lambda écrite en Python 3.9 qui capture les événements de changement d'état de tâche et d'instance de conteneur et les enregistre dans l'une des deux tables Amazon DynamoDB :

  • ECS CtrInstanceState — Stocke le dernier état d'une instance de conteneur. L'ID de table correspond à la valeur containerInstanceArn de l'instance de conteneur.

  • ECS TaskState — Stocke le dernier état d'une tâche. L'ID de table correspond à la valeur taskArn de la tâche.

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 )

L'exemple de Fargate suivant montre une fonction Lambda écrite en Python 3.9 qui capture les événements de changement d'état des tâches et les enregistre dans la table Amazon DynamoDB suivante :

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 )