Origin Story

Whenever I show this website to someone, they ask "Did you make this yourself?" The answer is, yes. It is a labor of love. There are easier and more professional ways to build a personal website but I wanted to hand-craft this from scratch as a learning experience. So, the next question is- "Can you explain me how did you build it?" The answer is this post.

Everything beyond this point assumes you have a basic understanding of Amazon Web Services (AWS), or can learn from the 'Getting Started' docs for the various AWS products.

Version 1: The Traditional Way using EC2 Virtual Machines

The original idea was simple- take a Linux machine, install Apache web server on it, and serve the index.html page from it. Then came the phase of making it secure, fast, and cost optimized using the cloud. One thing led to another and the final architecture looked like this-


Step 1: Build your website on your local machine. At the very least this will require creating an index.html page that defines the layout and content of your site. Ideally, you'd also create a separate style.css page to define all the style elements for various parts of your site, and reference it from your index.html.

Step 2: Purchase a domain name for your site, for example somecloudguy.com is mine. I got this from GoDaddy, but you can buy directly from AWS Route 53, or any provider of your choice. Decide what sub-domains will you use for various parts of your site, you will need this later. For example, I use www.somecloudguy.com as my main public-facing domain, but I also have all my static assets such as images served from static.somecloudguy.com. Why though? We will get to it in a few steps.

Step 3: Launch an Amazon EC2 instance to work as your web server. For high-availability, you can spin up two identical instances in two different Availability Zones. Install Apache on both instances. Upload your index.html file to /var/www/html directory on the Apache server. This will be the homepage of your website. Upload additional HTML pages, CSS files, and anything else you need to make your site render on a browser

Step 4: Create an Application Load Balancer (ALB) in the same AWS region where you spun up your EC2 instances. Add both EC2 instances in the Target Group for the ALB

Step 5: Create an Amazon S3 bucket. This is where you will store all the static assets for the site, such as images and videos instead of serving them from your web server. This way you do not need a giant disk volume attached to your instance to hold all the static objects. Create a folder structure of your choice and upload all the objects you need for the site. Remember to make the objects public if you want them to be accessible over the internet (but DO NOT make the entire bucket public!)

Step 6: Create a free SSL certificate from the Amazon Certificate Manager (ACM). Include all domain names you will be using for your site, you can make it easy by using wildcard domains. For example, I use *.somecloudguy.com so it covers both www.somecloudguy.com and static.somecloudguy.com

Step 7: Create CloudFront distributions for your domains. Since I am using two subdomains, I create two distributions. Configure them to use the SSL certificate you just provisioned, and force all traffic over HTTPS. Doing this is not just good from a security standpoint, but also helps remove the "Your site may be insecure" warning that Firefox and Chrome will display if you are accessing an HTTP (non-HTTPS) site. Point these distributions to the appropriate origins. For example, the distribution for www.somecloudguy.com points to the ALB created in Step 4, while the one for static.somecloudguy.com points to the S3 bucket created in Step 5

Step 8: Create a DNS record for your domains in Route53 to point them to the appropriate CloudFront distributions. Usually, you cannot point naked domains (without the www, for example) to an alias, but Route53 allows this if the alias you are pointing to is also an AWS resource. So, I have both somecloudguy.com and www.somecloudguy.com pointing to my main CloudFront distribution, while static.somecloudguy.com points to the other distribution

Step 9: Give it a few minutes for everything to be deployed, enter your website URL in your browser, and tada! Your website is live for all to see!

Version 2: The Modern Way using Containers

It is almost 2020, and the whole world is going crazy over Docker containers. So, it was about time to modernize my old-school architecture too. I decided to containerize my web server, and get my hands off managing them by using AWS Fargate that allows you to run Docker containers without worrying about the underlying servers or clusters. The fancy new architecture of my site now looks like this-


If you want to build this version, Steps 1 and 2 remain the same as above.

Step 3: Install Docker on your local machine. Create a file named Dockerfile. This is called a Docker image and it describes what needs to be installed on your container. Edit the Dockerfile to add commands to install Apache, and to copy all your site assets (index.html, CSS files, pictures, etc) from your local machine to your container. Build and run your Docker image locally and upload it to Amazon Elastic Container Registry (ECR)

Step 4: Create a task definition in Fargate, and configure the Service to set up two copies of your container task in two different Availability Zones, built from the image you uploaded to ECR in the previous step. It also creates an Application Load Balancer and registers the tasks as targets for the ALB

Steps 5 to 8 remain the same as in Version 1.

Step 9: Enter your website URL in your browser and bask in the glory of having created a fully-managed modern containerized cloud-based website that you can now show-off to the world on LinkedIn and Twitter!