I am trying to create an eventbridge rule whenever ECS task is deleted abnormally.
Normally ECS sends all events event the created or attached states too but I want to filter only DELETED
state.
I am using CDK to create my event rule. I am trying to implement content filtering based on status which is present in attachment field which is again a part of detail field.
Sample event from ECS Task ->
{
"version": "0",
"id": "3317b2af-7005-947d-b652-f55e762e571a",
"detail-type": "ECS Task State Change",
"source": "aws.ecs",
"account": "111122223333",
"time": "2020-01-23T17:57:58Z",
"region": "us-west-2",
"resources": [
"arn:aws:ecs:us-west-2:111122223333:task/FargateCluster/c13b4cb40f1f4fe4a2971f76ae5a47ad"
],
"detail": {
"attachments": [
{
"id": "1789bcae-ddfb-4d10-8ebe-8ac87ddba5b8",
"type": "eni",
"status": "ATTACHED",
"details": [
{
"name": "subnetId",
"value": "subnet-abcd1234"
},
{
"name": "networkInterfaceId",
"value": "eni-abcd1234"
},
{
"name": "macAddress",
"value": "0a:98:eb:a7:29:ba"
},
{
"name": "privateIPv4Address",
"value": "10.0.0.139"
}
]
}
],
"availabilityZone": "us-west-2c",
"clusterArn": "arn:aws:ecs:us-west-2:111122223333:cluster/FargateCluster",
"containers": [
{
"containerArn": "arn:aws:ecs:us-west-2:111122223333:container/cf159fd6-3e3f-4a9e-84f9-66cbe726af01",
"lastStatus": "RUNNING",
"name": "FargateApp",
"image": "111122223333.dkr.ecr.us-west-2.amazonaws.com/hello-repository:latest",
"imageDigest": "sha256:74b2c688c700ec95a93e478cdb959737c148df3fbf5ea706abe0318726e885e6",
"runtimeId": "ad64cbc71c7fb31c55507ec24c9f77947132b03d48d9961115cf24f3b7307e1e",
"taskArn": "arn:aws:ecs:us-west-2:111122223333:task/FargateCluster/c13b4cb40f1f4fe4a2971f76ae5a47ad",
"networkInterfaces": [
{
"attachmentId": "1789bcae-ddfb-4d10-8ebe-8ac87ddba5b8",
"privateIpv4Address": "10.0.0.139"
}
],
"cpu": "0"
}
],
"createdAt": "2020-01-23T17:57:34.402Z",
"launchType": "FARGATE",
"cpu": "256",
"memory": "512",
"desiredStatus": "RUNNING",
"group": "family:sample-fargate",
"lastStatus": "RUNNING",
"overrides": {
"containerOverrides": [
{
"name": "FargateApp"
}
]
},
"connectivity": "CONNECTED",
"connectivityAt": "2020-01-23T17:57:38.453Z",
"pullStartedAt": "2020-01-23T17:57:52.103Z",
"startedAt": "2020-01-23T17:57:58.103Z",
"pullStoppedAt": "2020-01-23T17:57:55.103Z",
"updatedAt": "2020-01-23T17:57:58.103Z",
"taskArn": "arn:aws:ecs:us-west-2:111122223333:task/FargateCluster/c13b4cb40f1f4fe4a2971f76ae5a47ad",
"taskDefinitionArn": "arn:aws:ecs:us-west-2:111122223333:task-definition/sample-fargate:1",
"version": 4,
"platformVersion": "1.3.0"
}
}
cdk code
{
eventPattern: {
source: ['aws.ecs'],
detailType: ['ECS Task State Change'],
detail: {
clusterArn: [cluster.clusterArn],
attachments: [{ status: [{ prefix: 'DELETED' }] }] // this is not working
},
},
}
CodePudding user response:
EventBridge can match scalars in an array, but not arbitrary objects in an array:
docs: If the value in the event is an array, then the event pattern matches if the intersection of the event pattern array and the event array is non-empty.
That means EventBridge cannot match only "status": "DELETED"
. What are your options?
- Base your pattern on a correlated non-array key-value pair, e.g.
"lastStatus": "STOPPED"
. - Match all patterns. Add logic to the event target to ignore uninteresting patterns.
Note: because you say the array reliably has only one element, you can transform the event detail before it gets sent to the target. This does not help with the matching problem, but can make downstream filtering easier. Here is a CDK example for a Lambda target:
rule.addTarget(
new targets.LambdaFunction(func, {
event: events.RuleTargetInput.fromObject({
status: events.EventField.fromPath('$.detail.attachments[0].status'),
original: events.EventField.fromPath('$'),
}),
})
);
The Lambda receives the reshaped event detail:
{
"status": "ATTACHED",
"original": <the original event>
}