Amazon EC2 – Setting Up AngularJS2 App with Route 53, CloudFront, and S3

amazon ec2amazon s3amazon-cloudfrontamazon-route53amazon-web-services

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 🙂

Best Answer

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.