Let's say I have a website: mysite.com, running on AWS, served from some EC2 instances behind an Application Load Balancer. The load balancer terminates SSL through an ACM certificate.

I need to route incoming requests to a URL (example: mysite.com/{user_id}/something/here/) away from the load balancer and instead send them to a Lambda function (more specifically, I want to just capture the request body and write it somewhere and then return an HTTP 200; it doesn't have to be done via a Lambda function).

The ALB lets you route to different target groups, but they can only contain EC2 instances it seems. The docs state "You register targets, such as EC2 instances, with a target group" - what else can be added if not only EC2 instances?

I don't want to have to run my own instance of haproxy etc, nor route them via nginx once the requests go through the ALB and hit the web servers, because the point of this exercise is to reduce things I have to manage, not increase them!

Is there a way around this?

  • Based on a review of the documentation (I haven't used ALB yet) it appears that you have to target EC2 instances. I think the easiest way to do this is via a proxy like Nginx. I wonder if the API Gateway could somehow play a part, but that would mean routing all requests through it. Can you have the client call a different endpoint for this request, a subdomain that's mapped to Lambda? If you edit your question to give more detail of your use case you might get better information. – Tim Jun 23 '17 at 18:37
  • My main concern is that if I proxy it with nginx et al, I have to maintain that instance and work to keep that up during traffic bursts, and I'm doing this to try and reduce redundancy by taking it as far out of my hands as possible. I can't modify the paths being called unfortunately either. – Marc Fowler Jun 23 '17 at 23:29
  • Something like API Gateway that lets you front an AWS service (DynamoDB, SQS..) sounds perfect to me but I can't see how to implement that into my existing setup as I need to intercept a URL going to the ALB and send just that to API Gateway, but leave everything else as going through the load balancer as configured. – Marc Fowler Jun 23 '17 at 23:32
  • If this setup is plausible API Gateway would probably be the primary gateway. I don't know enough about it to know if it is or not. I think you may be best off actually proxying via an EC2 instance. – Tim Jun 24 '17 at 1:00

You register targets, such as EC2 instances, with a target group.


You've made an astute observation. That's an interesting choice of words... but, for the moment at least, EC2 instances are the only kind of target.

An EC2 instance either invoking your Lambda functions or proxying them to API Gateway (with Nginx or HAProxy) is a reasonable way to go. If you're not familiar with using an instance just as a proxy, you'll likely be surprised at how much traffic you can push through even tiny instances when proxying is all the work they are doing. (I have t2.micro and t2.nano instances with HAProxy that proxy well over 1 million requests per day without ever exceeding 5% CPU).

But, if you want to reduce the things you have to manage, keep everything in one domain, and pluck off certain paths, you can use CloudFront in front of the ALB, to route certain path patterns elsewhere -- such as to API gateway. (Bonus: you can integrate static assets from S3 into your site with this solution, too. You can even route requests to servers and services external to AWS, by path pattern matching.) CloudFront is marketed as a CDN, but it also happens to be an infinitely scalable reverse proxy.

  • Nice answer! Why didn't I think of that, I use CloudFront! – Tim Jun 24 '17 at 1:29
  • Thanks for the advice guys - I really like the idea of doing this with CloudFront because it's less management etc. But, I don't like the idea of fronting my entire domain with CF and having to prevent it from caching non-static things etc. So I'm going to go with proxying with nginx/haproxy because I have more experience with it. Your other answer over at serverfault.com/questions/830050/… is likely very helpful also! – Marc Fowler Jun 26 '17 at 14:15
  • having to prevent it from caching non-static things etc. That's a fair point, but it's easy enough. If your origin server returns correct Cache-Control: headers -- which it should -- then CloudFront should do the right thing. I typically use the default cache behavior for non-cached resources (forwarding cookies, query strings, etc.), then create caching behaviors for things to cache -- *.css, *.png, *.js, etc. You should find that CF makes your entire site snappier even when resources aren't cached, because of the optimized transport paths it provides. Your call, though. :) – Michael - sqlbot Jun 26 '17 at 15:34
  • Oh absolutely, I really meant that as an aside in terms of moving over a pretty massive app to be fronted by a different service and then having to worry about some random thing accidentally cached that shouldn't have been like a static .html file that is stuck forever now (CF invalidations are slow/a pain). In the end, I'm proxying from ALB -> haproxy -> Kinesis -> Lambda, which is working very well! Thanks for the help - your other posts on haproxy have been really handy too! – Marc Fowler Jun 28 '17 at 21:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.