Long live williamdecesare.com

Navigating the intricacies of an AWS deployment for my personal website.

This is a follow-up post to part 1, where I discuss the merits behind a personal website and my process in redeveloping williamdecesare[dot]com. If you haven’t already, check it out!

Could Andy Jassy deploy an app on AWS?

That’s right: set up an AWS account, select the right dev tool(s), write and merge code to the instance, and set up networking such that you or I could access www.andycodes.com.1  

It seems like an outrageous question given that he built AWS from an idea to nearly $91B in annual revenue. He’s a career Amazonian and managed the development of, quite literally, every AWS developer tool. If there’s someone on this planet who knows the intricacies of AWS, it’s Jassy.

On the other hand, he’s not a trained software engineer. He studied business and started his career in marketing. Further, as you scale a company, you give away your legos. I doubt he spends time debating the differences between Lambda and Amazon-managed Airflow services, or Lightsail and Beanstalk.

Similar to Jassy, I don’t have any official software engineering training.2 I’ve never deployed an app on the cloud, and I started my career in marketing (analytics). And frankly, deployment always seemed daunting: the Almighty AWS, DevOps, EC2, clusters, Cloudwatch… I mean, how is one supposed to navigate this seemingly obfuscated world? There are disparate tutorials, unlimited options with overlapping capabilities, and naming conventions that have zero relation to the value they provide.3 Where do you even begin?

Spoiler: williamdecesare.com v2 is now live on AWS.
Buyers beware: I’d like to see Andy Jassy give it a try.

Me, searching for dev tools on the AWS console.

Scope

I set one goal for this project: deploy my site. I ultimately broke down the scope into a few steps:

  1. Find a host: find a hosting service to run my website’s app.

  2. Run app on hosted service: configure the service, migrate the app, and ensure it runs accordingly.

  3. Manage DNS and security: point the domain name to the server and configure secure networking.

While there are other areas of opportunity for improvement, I kicked those down the road.

Deployment

Fortunately, I found a few solid tutorials on app deployment.4 I do not want to spend time (or your attention span) rehashing those tutorials, so I focus on my experience building and troubleshooting.

Find a host 🏠

Think of hosting services (AWS, Google Cloud, etc.) as literal warehouses with tons of servers (i.e. computers) that can be rented out to people like you and me. In the early aughts, Amazon found a niche in the market by monetizing the computing infrastructure that serviced amazon.com, and other tech companies quickly followed suit. I mean, who wants to spend their time monitoring the temperature of a computer to keep a website running 24/7? (answer: no one).

There are generally two paths to deployment: fully-managed and self-managed solutions. Fully-managed solutions equate to “pay more for out-of-the-box functionality but less flexibility”, while self-managed solutions equate to “here’s access to a server in Virginia - figure out the rest”.

I ruled out self-managed solutions pretty quickly because I did not want to deal with load balancing and Kubernetes clusters (you are welcome for sparing the details here). Further, I narrowed down to a few fully-managed solutions pretty quickly: AWS Beanstalk, AWS Lightsail, Heroku, and DigitalOcean Droplets, and I leveraged Claude (among other threads linked in the footnotes) to summarize the pros and cons of each service:

I found Claude adept at creating a vendor comparison table; one without the “our features are five-stars, others’ features are not” part.

I chose AWS Lightsail for the following reasons:

  1. I have some familiarity with the management portal.5

  2. While your compute is capped (i.e. the site would stall if >X folks visit at any given time), so are your costs (~$7/mo).

  3. The out-of-the-box, default options would save time on infrastructure configuration.

and I didn’t look back.

Run the app on a hosted service 🏃

How can I run my app on this random computer in Virginia? Or, even better, how can I access this random computer in Virginia?

Lightsail allows you to connect via SSH. Think of SSH as a private tunnel to connect to your remote server, whereby using key validation, only your machine has access to the tunnel.6 It’s pretty straightforward to create an SSH key pair on your local machine, upload the public key to the console, and access the remote server from your machine.

Once I had access to the remote server, I moved the app files to the server, installed the required packages, and ran the app. Ideally, your app code is managed via a CI/CD service like GitHub, but to get something running, I manually copied the files, installed the packages, and ran the app. I faced a bit of difficulty setting the right ports (for development, I used port 8000 and this ended up working fine), and I used a popular server package to run the app 24/7.7

After setting up a Static IP address in the Lightsail console, I could type the Static IP in my browser and access my site 💪

Managing DNS and security 🔒

Managing the DNS (Domain Name System) was by and large the thorniest piece of this project. I eventually landed on the following system design:

Some of the setup included:

  1. Setting AWS name servers in Namecheap DNS.

  2. Create a hosting zone in AWS Route 53 to allow redirects from the williamdecesare.com domain to my remote server.

  3. Configuring a reverse proxy to handle my domain name and Static IP.

  4. Configuring SSL certification (i.e. “https” instead of “http”) to ensure encrypted connections from the client (i.e. your computer).

I could write an entire article on proxying, but the short version is that it allows your website to appear under your custom domain name instead of the default AWS URL, while AWS handles all the actual web traffic behind the scenes.

After what felt like thousands several configuration changes, service restarts, and browser refreshes, it finally worked!

It’s out in the wild 🥹

Future iterations

I plan to prioritize the following few big-ticket items over the next few months as a way to drive site traffic and more effectively share my story:

Configure CI/CD: To make any changes in the app today, I must manually copy the app code and restart the service. In the future, I plan to manage all code changes in GitHub and easily merge these changes via GitHub actions. This will come in handy as I slowly iterate the site’s overall design.

Optimize to mobile: chances are you are looking at my website from a mobile device (over 60% of all internet traffic, depending on the source), and if so, you’ll notice that things are a bit off. I plan to apply plenty of out-of-the-box frameworks to improve the user experience and alleviate some of the pains of frontend design.

Embed an app on the site: it would be interesting to run an embedded app within the site, potentially to collect email addresses, introduce a contact form, or something similar. This coincides with most B2B or B2C SaaS products but requires a larger engineering effort.

Closing Thoughts

  1. Deployment is not for the faint of heart. I may or may not have checked Heroku pricing and been tempted by a Squarespace ad in the making of this project. Deployment is complicated, and I would recommend a more hands-off service (like Squarespace) for most people.

  2. Do not get trapped in the rabbit hole of system design. Tens of systems could fit your use case, and many systems overlap. Plus, if you read three opinions on system design, it’s not unlikely to receive three conflicting opinions. Spend some time researching, yes, but invest the most amount of time actually deploying the app.

  3. The networking space is vast. I now realize the importance of Cloud Infrastructure Engineers and no longer underestimate the complexity of their work. Previously, I didn’t know what I didn’t know, but now, I can only imagine the effort and coordination required to keep a company like Apple humming at scale.

Before I sign off, make your voice heard in the poll below 👇

1  This is an unclaimed domain, but for $995 (or $0.50 to the median American household), it could be his!

2  In full transparency: I took 2 sessions of an intro Python course where, after I sent my code in for review, they told me that I was too advanced for the class (weird flex, I know).

3  Re: AWS Elastic Beanstalk: “The name "Elastic beanstalk" is a reference to the beanstalk that grew all the way up to the clouds in the fairy tale Jack and the Beanstalk.” - Wikipedia. But why?

4  I found these threads (one, two, three) to be the most helpful for researching system designs, and these tutorials (four, five) most helpful for navigating AWS Lightsail deployment.

5  I’ve managed an Amazon Managed Workflows for Apache Airflow (MWAA) deployment and have familiarity with the AWS environment through that experience.

6  Checkout this Cloudfare link for a more detailed description.

7  A port is “a virtual point where network connections start and end” (thanks again, Cloudfare).