Deploy an Angular with S3 and CloudFront

Kittiphat Srilomsak
5 min readApr 30, 2018

--

Here is how easy it is to deploy an Angular SPA (Single Page App) as a static website using S3, and with help of CloudFront for redirection.

Idea

So here is the basic schematic of what’s going to happen.

                    +----+     +------------+
Compiled angular -> | S3 | <-> | CloudFront | <--> Internet
(/dist folder) +----+ +------------+

Compile the Angular Project

Basically run angular’s cli compiler.

$ ng b -prod — aot

When finished all your files will be stored within dist/ directory.

Deploy it on S3

First thing first, you need an account with S3, So I assume you already have that.

  • Head to S3 console
  • Create a bucket. (Make sure you grant a public read permission to Public — Set Permissions / Manage public permission — and Grant public read access to this bucket.)
  • In your bucket, go to Overview tab and upload everything in your dist/ to your desired folder (or you can place all of them in root). Again upon upload make sure you grant Read permission to Public for all the objects that has been uploaded.
  • Update S3 properties to static website hosting, Go to Properties tab. Select static website hosting. Put in index.html in index document.
  • That’s it. You website is up and running. You can try it by navigate to your URL. as follow:
https://<bucket-name>.s3-website-<region>.amazonaws.com

Note: This URL actually already provided in Properties tab under static website hosting of your bucket.

Try use this link on your browser your angular project should be up and running.

Now there is still some problem. If you Angular Project does use routing mechanism. As in this official example. Your project will not function properly when you use full URLs. Basically this https://<bucket-name>.s3-website-<region>.amazonaws.com/some/route/path will not work. As S3 will try to find an object based on your given some/route/path of which it cannot be found. So how can we fixed this?

Here is when CloudFront come to rescue.

CloudFront for Routing rules

So the idea is as simple as whenever S3 reply 403 or 404 we should return content from index.html instead and return status 200 instead.

Here is how to do it.

  • Go to CloudFront Console
  • Add new Web Distribution
  • Important: Origin Domain Name will provide you with the drop down of S3 bucket. You shouldn’t use that. As it omitted the S3’s region and it will cause the request to redirect instead of passing through the traffic through CloudFront. (May be there is a better way to configure this I’m not sure.) So just copy-and-paste your S3 URL here. <bucket-name>.s3-<region>.amazonaws.com .
  • You should configure Origin Path to your S3 root folder name if you decided to upload your S3 on non-root folder.
  • You should configure Alternate Domain Names (CNAMEs) to your custom subdomain if you decided to let this website accessible from other hostnames. (You should also have the DNS CNAME records point to this CloudFront’s distribution).
  • Head down to Default Root Object setting. And set it to index.html
  • You can leave pretty much everything else default. And note that you can come back and reconfigure all of these at anytime.
  • Save.

Now if the Distribution’s status is showing in-progress for more than 5 minutes. That means something is wrong. You should go check if your S3 is really accessible for your CloudFront’s configurations. And also check if your CloudFront’s configuration is correctly configured. (Such as Origin Domain Name).

  • Once your distribution is up and running you should be able to access your website through CloudFront. Your CloudFront URL is in the console under DOMAIN NAME column.
  • Copy-and-paste that on your browser see if it correctly shows.

Finally, now we need to configure 403 or 404 errors to redirect the traffic to index.html to do this.

  • Go to Distribution Settings
  • Go to Error Pages Tab
  • Create 2 Customer Error Responses for 403, and 404 error. Both of them should use Customize Error Response with page of index.html and change status to 200.

That’s it! Now you should be able to link to your website through CloudFront’s domain name with any path. Try.

https://<cloudfront>.cloudfront.net/some/path

Configure CNAME

Now if you want your URLs to look pretty. You can configure CNAME to point to this CloudFront’s URL.

Once you have your CNAME added. Comeback to CloudFront’s distribution and update your Alternate Domain Names (CNAMEs) Wait for couple minutes and try it out.

In my case I use cloudflare.com to configure my DNS, and offload some traffic from my AWS account.

Secure your S3 Bucket (Optional)

As of now you would have the Cloud Front distribution up and running you can now enclose your S3 bucket public access. To do this. You will need to stop the distribution of your Bucket publicly. And instead, configure your CloudFront distribution to use its own AccessIdentity.

To do this

  1. In your S3 Bucket, remove public access.
  2. In your CloudFront distribution, go to Origin and Origin groups tab.
  3. Select your S3 Bucket, hit Edit
  4. Select ‘Yes’ to Restricted Bucket Access.
  5. Select your desired Identity, and check ‘Yes, Update Bucket Policy’ so that CloudFront update the Bucket Policy for you.

Update the site

Last tip about using this configuration to host your website. With this configuration, CloudFront will copy and caches your files when it necessary. And that means a lot of cache has been saved. So when you re-upload your content to S3. It might not take effect immediately.

There are few ways to fix this.

  • Invalidate the cache. In CloudFront console, under your distribution’s settings. You will have an Invalidations tab. Under this tab you can request CloudFront to clean up its caches. All you need to do is to provide the list of files you need to clean up. For project like Angular. All the files are linked by index.html so basically what you need is to clear them out. (Unless you have some changes files in your assets directory). But this should be pretty straight forward.
  • Another solution is to separate the S3’s root folders into versions. And upload them by versions. Once uploaded you have to fix CloudFront’s distribution Origin Path to the correct version.
  • S3 also have Versioning properties which I haven’t explored them yet if it would be a good fit to solve this problem or not.

Anyway that’s how you can deploy Angular, S3, and CloudFront.

--

--