Search code examples
amazon-web-servicesamazon-ecsaws-application-load-balancer

AWS ALB target group path based routing not working when I change the path


EDIT

I have discovered that adding a route to the node app under /cms seems to resolve the issue, however, how can I point to / as the default. This seems like annoying behaviour

END EDIT

I have an ECS Cluster with one task running, this is picked up by a target group and on the ALB I was routing to this target group on / like below:

enter image description here

When I then grab the DNS from the ALB and hit the url it works fine, I get:

{"name":"DEMO"}

I want this service to be routed too only when the user hits /cms, so I changed this in the listeners like so:

enter image description here

However once updated and I hit the url + /cms I get:

Cannot GET /cms

And I cannot work out why. This is a super basic node express app with the index like below:

const express = require('express')
const app = express()
const port = 80

app.get('/', (req, res) => {
    let data = {
        name: "DEMO"
    }
    res.json(data);
})

app.listen(port, () => {
    console.log(`Example app listening at http://localhost:${port}`)
})

Solution

  • HTTP Request is:

    http://yourdomen/[path]/[subpath]
    

    where: [path] - It wether /cms or /

    There is Load Balancer forwarding behaviour:

    • If Load Balancer get http://yourdomen/, it pass http://yourdomen/ to Express (not /)
    • If Load Balancer get http://yourdomen/cms, it also pass "http://yourdomen/cms" to Express without any changing (not /cms)
    • If Load Balancer get http://yourdomen/cms/[subpath], it pass http://yourdomen/cms/[subpath] (not /cms/[subpath])

    Load Balancer can't pass only subpath part to Express in "Forward to" action. If you want to Load Balancer change your Request before pass it to Express, you should use "Redirect to" action

    NOTE you can use ECS cluster private DNS as host in a redirecting rule, then you won't need a target group

    Redirect example:

    Load Balancer gets http://yourdomen/cms/[subpath] and changes the request's route to http://dummycmsdomen/[subpath] and redirect this updated route to Express. In this case Express will get http://yourdomen/[path] pattern, and works correctly within your scenario

    EDITION PART ANSWER:

    • If you send http://yourdomen/ then Express should works with / path
    • If you send http://yourdomen/cms then Express should works with /cms path

    So before you edited code Express app it were waiting for / path, but it get /cms and should return GET-error. And after you have added an according directive to process /cms path App became to works