Amazon Web Services is an on-demand cloud computing services platform offered by Amazon. In simple words - they offer many services like file storage, databases, DNS, and servers you can use on their infrastructure.
Configuring infrastructure on Amazon Web Services (AWS) for the first time may seem painful. At first, it is not easy to get around the AWS web console as there are a lot of services and configuration options. Especially when we compare it to alternative services like Netlify or Vercel. But is it really that hard? I'll try to show you that it actually isn't.
This article is aimed at beginners who want to gain hands-on experience with AWS. I will show you how to create infrastructure for your single page application by clicking through the AWS web console. I believe the web console is a great introduction for first-timers as it makes it easier to understand all the services you will use. You can use that experience later if you would like to define your infrastructure with code. With Terraform and infrastructure as code, you will be able to spin up all those services with just one command.
You may think: Why can't I just use the static website serving option in S3? The most important differences are cost, performance, and configuration options. While S3 was designed as a simple (hence "simple" in the name) object storage service, CloudFront is more like a CDN - it will allow you to cache and serve your content from the location closest to the client. It is also cheaper and offers a lot of useful configuration options, including the powerful Lambda@Edge. Speaking about costs - if you want to serve a small website, the most expensive thing will be a Route 53 hosted zone - $0.50/month :) You can find more about the costs on the AWS website.
In this article, we will create a fully functional production environment for a frontend application. To achieve that, we will add our domain to Route 53, create an S3 bucket, CloudFront distribution, and generate an SSL certificate. I will guide you through the AWS web console step-by-step. After following the instructions in this article you should get hands-on knowledge about a few AWS services and the AWS web console. Note: I will not cover continuous integration configuration here and we will deploy by just uploading files to the bucket.
Before we start you will need:
If you want to play around with AWS you can create an account and take advantage of Free Tier (https://aws.amazon.com/free/) which will allow you to test AWS services for free. You can also create free domains on freenom.com.
Domain Name System is the phonebook of the internet. The general purpose of a nameserver is to translate domain names to IP addresses. So when you type in netguru.com in your browser, first there will be a request to a DNS server to obtain the site's IP address. Using the Route 53 DNS service from AWS you can configure your domain's DNS records or even buy a new domain there.
We will start by adding existing domain name servers to Route 53, which will allow us to manage DNS Records within AWS.
Now it's time to “connect” our domain to our hosted zone.
Warning: If you have other services attached to your domain - like email or subdomains - those will stop working after changing nameservers. So unless you know what you are doing I suggest creating a new domain to play with AWS - you can get a free domain on freenom.com. It is possible to retain all existing services but it requires different configuration.
AWS Simple Storage Service, or S3, is an object storage service from Amazon - basically you can store files there. Objects in S3 are organised into Buckets. You can think of it as the highest-level directory for your files. Usually we create a bucket per app, or per context (environment) - eg. 1 for app files and 1 for app logs. Let’s create a bucket where we will store our app.
Now you have it on your bucket list :)
An SSL Certificate enables secure (encrypted) communication between a user's browser and your server. It also authenticates the identity of the website - that’s why it is issued per domain name. Certificates are issued by Certificate authorities (CA). You can find out more here: https://howhttps.works/
We are setting up production, so SSL is a must. Thankfully, we can request certificates for free from AWS. Using ACM - a certificate manager provided by AWS - you can request and manage SSL certificates for your domain.
From the user’s perspective it is best to receive data from the closest (geographically) location. So if I’m in Warsaw, Poland a request to North Virginia will take longer than a request to Frankfurt. To achieve that we will use CloudFront - a Content Delivery Network from AWS. A CDN is a bunch of globally-distributed servers that cache your content to improve access speed for end users. CloudFront distributes content using Amazon's edge locations which are located in major cities around the world to reduce latency.
We are now ready to configure CloudFront distribution (finally!).
Fill in Origin Settings:
Fill in Default Cache Behavior Settings. I will leave most of the options with default values so here are the ones you should change:
Fill in Distribution Settings:
Now you can click Create Distribution to submit the form. After that you can see your distribution after selecting Distributions from the left menu within the CloudFront section.
We have to make our domain point to CloudFront distribution. To do that, we will create DNS records for our domain in Route 53. If you want to learn more about DNS records, take a look at https://www.cloudflare.com/learning/dns/dns-records/. We will create A alias and AAAA alias records - in general A/AAAA records point to IP addresses, but AWS also offers alias records to route traffic to AWS resources using a domain name. You can read more here: https://aws.amazon.com/route53/faqs/.
Let’s go back to Route53 using the services menu. In the Route53 Hosted zones area click on your domain name (in my case: depguru.ml).
We need to create 2 record sets (IPv4 and IPv6) for each subdomain. I have 2 subdomains (depguru.ml and www.depguru.ml) so i will create 4 records in total.
So repeat steps listed below for:
After that you should have 4 A/AAAA records.
But wait, what's going on here?
We’ve set our DNS server to redirect users to our CloudFront Distribution.
So when a user asks
> Where can i get the depguru.ml website?
He will get the answer:
We had to set it for both IPv4 and IPv6, and also for the www. subdomain as I wanted www.depguru.ml to point to my CloudFront Distribution. (note: www.depguru.ml and depguru.ml are in fact different domains and can point to two different sites).
Our app is working now, but as this is a single page application the frontend takes care of routes. So it works fine when the user enters the app using the “/” path, but doesn't work when it starts from another page like “/users”. That’s because CloudFront serves index.html on / (we set the default Root Object to index.html) but doesn’t know what to do with other paths.
We can solve that with setting a fallback - tell CloudFront to redirect to index.html if it can’t find a file. This is probably not the best solution (may hurt SEO in some cases as it may return 200 for non-existent pages) but it is the simplest, so I’ll go with that.
To redirect error pages to index, you have to:
After that if you head straight to https://depguru.ml/about you should still see my app.
Now our infrastructure is ready to serve content… but we have no content yet! If you visit your domain now you will probably see an Access Denied error from S3.
We need to deploy our app to the S3 bucket now. For the sake of simplicity I'll just go to S3 in the AWS console and upload files to the www directory in my bucket using the GUI.
Now you should see the www directory and its contents.
After that, my app is available at depguru.ml
Note: Propagation of changes in DNS may take time (up to 24 hours) so don’t panic if you can’t see your site right away.
So now we have a fully functional production environment on AWS! That wasn’t that hard, was it? It took me about 30 minutes to set up everything on my first attempt. The AWS console seems scarier than it in fact is.
Of course it is hard to contain all DevOps and AWS knowledge in one article, so I had to simplify things here and there and chose a simple use case to show the basic principles. But I still think it's a good starting point if you are interested in the subject. In general it is better to create infrastructure with code (see: Terraform) but if you are taking your first steps with AWS, I think using the GUI (the way shown in this article) is a good starting point.
Note: Be careful with credentials and selecting options. AWS bills you for usage, so doing something stupid may result in a huge bill at the end of the month. Also if your credentials leak somewhere, someone can use your account (and credit card) for things like mining cryptocurrencies.