9

I am trying to get an AWS Lambda function to run whenever a new image is pushed to an AWS container registry. I have created and tested the function which works fine. I have then created a simple CloudWatch event rule with the pattern:

{
  "source": [
    "aws.ecr"
  ]
}

which I believe will trigger on any event from ECR.

The rule has a target of the lambda function. The problem is the function is not called when a new image is pushed to the registry (or deleted etc). Nothing appears in the CloudWatch logs for the function. Is there something missing from the event rule or a way to diagnose what could be going wrong?

theduck
  • 2,589
  • 13
  • 17
  • 23
  • Could you share the full detailed as an answer to your own question? would definetly vote that up :) I have the exact same task and I'm quite new to this stuff, I would settle for the lambda code you used. – Naim Salameh Jan 25 '18 at 16:28

1 Answers1

10

CloudTrail records PutImage event and can write it to CloudWatch Logs. An Alarm can be triggered whenever a PutImage event is written in CloudWatch Logs which can further trigger a Lambda Function through SNS.

You would create a Logs Metric Filter, Something like this.

{ ($.eventSource = ecr.amazonaws.com) && ($.eventName = PutImage) && ($.requestParameters.repositoryName = “<RepoName>”) && ($.errorCode NOT EXISTS) }

or

You need to configure the ECR CloudTrail API Calls Events.

{
  "source": [
    "aws.ecr"
  ],
  "detail-type": [
    "AWS API Call via CloudTrail"
  ],
  "detail": {
    "eventSource": [
      "ecr.amazonaws.com"
    ]
  }
}
joeymiller
  • 283
  • 4
  • 9
  • OK. So this seems to work although it seems pretty convoluted for something quite straightforward (AWS not making life simple). So I have set Cloudtrail to log into Cloudwatch (it was already doing that), created a logs metric filter as you describe and then added an alarm to that filter which publishes a message to an SNS topic. The lambda function then subscribes to the topic and is therefore invoked when a message arrives in the topic! Not sure if there is a simpler way? – theduck Nov 21 '17 at 17:41
  • 2
    So, the second technique seems to work as well (and seems much neater). I created an Event Rule in Cloudwatch with a pattern as above except with eventName added so that I am only getting PutImage events. Target is then set to the lambda function which is called each time a new image is uploaded. Thanks for your help. – theduck Nov 21 '17 at 18:25
  • This approach works, but you couldnt you also trigger directly when Cloudtrail pushes to S3? This would also avoid the delay in cloudtrail pushing to cloudwatch. – rix Jul 09 '18 at 19:49
  • Yes - triggering of S3 works as well. Here is the guide for anyone who wants to go that route: https://docs.aws.amazon.com/lambda/latest/dg/with-cloudtrail.html. The only downside I can see with the s3 route is that I can't see an easy way to filter the events before the Lambda is called. It does remove the delay in Cloudtrail pushing to Cloudwatch although it seems like the main delay is in the Cloudtrail part. – theduck Jul 24 '18 at 15:03