1

I am really confused about the setup I need for my angularjs2 app.

It's simply a SPA application with html5 mode urls and all I want is:

  • requests to www.mydomain.com/blabla... will be redirected to the same mydomain but without the www
  • requests to mydomain.com/anything/including/path/like/this will give the s3 (/cloudfront) index.html
  • requests to mydomain.com/path/or/not/path/file_that_ends_with_any_extesnion_like.js will serve that file from the s3 (/cloudfront) if it's too hard I can also set up my website so all that assests will be in the assets folder so requests to mydomain.com/assets/path/blabla.bla will serve the static file from the s3 (/cloudfront)
  • and last but not least requests to mydomain.com/api/... will redirect to the ec2 instance which holds my REST API node.js server

Normally I would just use 1 ec2 instance with nginx and node.js while nginx try_files and if it fails it gives the index.html file and if the url is /api/.. it redirects the request to the api that sits on the same ec2

The problem with that setup is that it doesn't scale well and hard to maintain if you have more than 1 ec2 instance

I looked a lot in google but I can't find any guide or a blog post about how to setup something like what I described in the AWS cloud.

Thanks in advance :)

5

requests to www.mydomain.com/blabla... will be redirected to the same mydomain but without the www

This is done by creating an empty bucket in S3 named www.example.com, configuring it to redirect all requests to a different hostname (example.com) and pointing DNS at it.

If you want it to support https request redirection on the www side, you create a second CloudFront distribution for the www hostname, pointing to the web site endpoint for the bucket, and point DNS to CloudFront.

requests to mydomain.com/anything/including/path/like/this will give the s3 (/cloudfront) index.html

Configure the example.com bucket (the one with your content, not the empty one discussed above) for static web site hosting, and set the index document name to index.html in the bucket's static web site hosting configuration options. As discussed in the S3 documentation, when the S3 web site hosting feature is enabled for the bucket, the named index page from the appropriate place in the bucket will automatically be returned by S3 wherever possible, according to these rules:

  • If the the path requested is /foo/bar/ (with trailing slash) then S3 looks for an object with the key foo/bar/index.html and returns it, leaving the browser's address bar unchanged.

  • If the path requested is /foo/bar (no trailing slash) and foo/bar/index.html exists, then S3 returns a redirect to /foo/bar/, which results in the behavior described above, after the trailing / appears in the browser's address bar. (This is redirection to add the trailing slash is standard web server behavior; otherwise relative links in the index page will pointing to the wrong directory).

Instead of selecting the bucket from the drop-down list in CloudFront, you need to type in the web site endpoint hostname for the bucket, when setting up the CloudFront origin. Otherwise the web site features like index documents won't be enabled:

Important

Do not select the name of your bucket from the list, such as example.com.s3.amazonaws.com

http://docs.aws.amazon.com/gettingstarted/latest/swh/getting-started-create-cfdist.html

Next issue:

requests to mydomain.com/path/or/not/path/file_that_ends_with_any_extesnion_like.js will serve that file from the s3 (/cloudfront) if it's too hard I can also set up my website so all that assests will be in the assets folder so requests to mydomain.com/assets/path/blabla.bla will serve the static file from the s3 (/cloudfront)

You can configure CloudFront to choose which "origin" (back-end system) a request will be sent to, using cache behaviors, each of which matches a path pattern. It sounds like, in this case, you'd want your default cache behavior to point to the bucket, which will send all requests there, if not matching another cache behavior.

and last but not least requests to mydomain.com/api/... will redirect to the ec2 instance which holds my REST API node.js server

Presumably you don't really mean "redirect" but instead you mean "forward" or "proxy" (same thing) requests to the EC2 instance.

Declare the EC2 instance as another origin in the CloudFront distribution for your site. Create a new cache behavior matching path pattern /api/* that uses this origin, and CloudFront will send these requests to your EC2 instance.

Be sure your code on EC2 returns appropriate Cache-Control: headers on API responses so that CloudFront will cache them for an appropriate amount of time, or not at all if you return Cache-Control: no-cache.

Note that on cache behavior path patterns, a missing leading slash is implicit, so api/* is equivalent to /api/*.

Note also that CloudFront has a setting called "origin path", an attribute of the origin, which sometimes people get confused with "path pattern," which is an attribute of cache behaviors. Leave "origin path" blank, because it is not related to the paths you want to send to a particular origin.

  • Thanks a lot! this answer is pure gold, I see that I thought about route 53 as the place where I configure all those "special" route handlers but seems like cloudfront is actually the place for this right? another question regarding the index.html you said to just put the index file as index.html and it will automatically be returned? if cloudfront points to my S3 bucket for all the requests other than /api/* how would it know that I always want the index.html file from the bucket except when there is a file with that path in the bucket (or if path starts with /assets/*) – kfir124 Jun 6 '16 at 11:37
  • I saw a guide that uses this trick with a custom 404 error kkob.us/2015/11/24/… the question is if thats the right way of doing it? seems a bit hacky – kfir124 Jun 6 '16 at 12:20
  • No, you shouldn't need to use that hack. If you meant http://example.com/anything/including/path/like/this would actually display the contents from http://example.com/anything/including/path/like/this/index.html then I have updated the answer to explain more clearly how that works. On the other hand, if you mean no matter what's requested, then display the main page (e.g. /index.html) then that requires a different solution. Please clarify. – Michael - sqlbot Jun 6 '16 at 19:54
  • If you wanted http://example.com/anything/including/path/like/this to redirect to http://example.com/?uri=/anything/including/path/like/this, so that the root /index.html would be displayed and could take the rest of the "path" and handle it as a query string, this can be accomplished with S3 routing rules. Any request sent to the bucket where the file doesn't exist will redirect as shown. – Michael - sqlbot Jun 6 '16 at 19:58
  • Yes I meant that requests to http://example.com/anything/including/path/like/this will serve the root /index.html file but I still need the url to be displayed like http://example.com/anything/including/path/like/this ( I think redirecting to the #/anything/including/path/like/this hashbang url will cause angular to automatically transfrom the url to what I need) – kfir124 Jun 7 '16 at 13:03

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.