2

everyone. I have a case about CloudFront + S3 + ECS(ALB).

  • S3 bucket (enabled static web) (CSR - SPA) include: /index.html /admin /static/(file media)
  • ECS + ALB: 1 cluster Fargate run web backend

So, the design like this picture:

CloudFront + S3 + ALB

I configured CloudFront behavior.

  • Path pattern: /internal/* -> Origin ALB
  • Path pattern: Default(*) -> Origin S3. S3 used the custom origin with s3 static web url not user the alias.

Result

When I request CloudFrontURL, it shows me the /index.html on the S3 bucket. (It's correct).

But when I request CloudFront/internal. It didn't show me the 404 code. enter image description here

Then, I find the solution with lambda edge.

(link:

https://medium.com/radon-dev/redirection-on-cloudfront-with-lambda-edge-e72fd633603e

Hosting multiple SPA web apps on S3 + Cloudfront under same URL

).

I modify the example code in the link. My code:

var path = require('path');
var url = require('url');
exports.handler = (event, context, callback) => {
  // Extract the request from the CloudFront event that is sent to Lambda@Edge
  var request = event.Records[0].cf.request;

  const parsedPath = path.parse(request.uri);
  const parsedURL = url.parse(request.uri);
  // Extract the URI from the request  
  var olduri = request.uri;
  if (parsedURL.path.includes('/internal')) {
    var newuri = "EC2Co-EcsEl-1KE5FOHEHN2NH-230429797.ap-southeast-1.elb.amazonaws.com";
    request.uri = newuri;
    console.log("alburi =" + " " + newuri);
  } else if (parsedPath.dir.includes('/') && parsedPath.base != 'index.html' && parsedPath.dir != '/admin') {
    var newuri = olduri.replace(parsedURL.pathname, '/index.html');
    request.uri = newuri;
    console.log("rooturi =" + " " + newuri);
  }
  // Return to CloudFront
  return callback(null, request);
};

Result

  • When I request to the CloudfrontURL/ or CloudFrontURL/abcdxyz... or CloudFrontURL/something.. -> the response is the /index.html (Correct)
  • When I request to the CloudfrontURL/internal* -> the response is 502. like this

enter image description here

Please, help me. Sry about my English skill.

Lambo OP
  • 65
  • 8

1 Answers1

2

If you look the error, that means the cloudfront try to get the internal from S3 instead of the ELB. I suggest you to change your behaviour to have more simple :

1.Create a behavior that specifies a path pattern to route all static content requests to the S3 bucket. For example, you can set the "images/*.jpg" path pattern to route all requests for ".jpg" files in the images directory to the S3 bucket.

2.Edit the Default (*) path pattern behavior and set its Origin as your load balancer.

Or you can have this for example, two behaviours to two origin

enter image description here

Hatim
  • 1,116
  • 1
  • 8
  • 14
  • thank for your solution. i will try it. but my customer want the path **"/"** route to /index.html on s3 bucket. and the **"/internal** route to ALB. – Lambo OP Feb 10 '22 at 15:03
  • do u have another idea? – Lambo OP Feb 10 '22 at 15:21
  • i updated the solution used lambda edge. – Lambo OP Feb 10 '22 at 15:23
  • @LamboOP, there is no need to use lambda atedge, you can just use behaviours, the problem with lambda is if you have new cloudfront, you must change the url dns in your lambda, check the image posted – Hatim Feb 11 '22 at 10:43
  • oh. i re-config the behavious. then, it works without lambda edge. thanks for your help – Lambo OP Feb 14 '22 at 04:38
  • Hey Lambo, could you tell me how can do that? I configured behaviours as yours and Hatim suggestion but it does not work. – lex_luther_9x Aug 29 '22 at 09:04