I have written a lot of code over the years. From HTML and CSS in my early years to Java programs in college, to now professionally moving to mostly Python or JavaScript. I have written code because it was required for classes, written scripts to make my life easier in some way, or even rage coded because a meal delivery service’s food kept arriving warm with melted ice packs. For the first 10-15 years of my developer journey, I ran all of my code locally, on my machine, occasionally using tools like ngrok to bridge gaps with the oustide world.
Then came the cloud. Amazon Web Services (AWS) changed how I approached development. With Lambda functions I could quickly write my code directly in the cloud and attach it to an Amazon API Gateway. This allowed me to have the same functional results as ngrok on my home server but without the security concerns. As the cloud matured, so did the suite of tools to expedite cloud deployment. Since my development for work changed as my role changed, I mainly wrote quick scripts here and there and those tools seemed like overkill. Why would I use CloudFormation, Terraform or other Infrastructure-as-Code (IaC) to deploy a Lambda that was just making a basic API call?
And then I tried it.
I started a side project that required a website in Node. Key requirements were authentication for some pages and a small footprint. In the cloud everything is “pay by the drink,” a phrase a colleague introduced me to describing how every single service or interaction has some usage-based charge associated with it.
After I had a core of the site built locally, I started looking at how I was going to host this. I had hosted static sites in S3 but since this was written in Node, I had to think about all of my options. I could use Lightsail but the footprint on there was overkill for what I was doing. To get tactical I could leverage Elastic Compute Cloud (EC2), Elastic Beanstalk, Elastic Container Service (ECS) or Fargate to make things super simple. But after thinking through my expected traffic and some napkin math on cost, I decided I could take a chance with my tried and trusted friends, Lambda and Amazon API Gateway.
To take this route, I needed to refactor my code. When there is a Node server running, the app is always listening and can have some understanding of what is happening along the journey. With a static site, every interaction is somewhat unique and standalone except what is stored in the user’s browser. Since each interaction is unique, I needed to update my approach to how I was leveraging cookies and how authentication was managed along with other challenges including handling cold starts, CORs (Cross-Original Resource Sharing), Origin behaviors, and other fun with browser behavior with Cloudfront that I had never encountered before.
While trying to figure out this out, I discovered Serverless Framework, which would allow me to use a YAML configuration file to push my code from my local machine and to have it automatically spin up the services required in AWS. This allowed me to focus on the code I was writing as opposed to the how I configure the AWS services. The time to learn the framework was short and with new issue I encountered, it made troubleshooting and iterating significantly faster as I could push code and 30 seconds later all changes were made in the cloud on various services.
This process really opened my eyes as to how quickly and efficiently I could update code and make changes and integrate that with a CI/CD pipeline. I also learned many new valuable skills with a desire to update some old work based on these findings. Some of the things of note I learned:
- New AWS services - Amazon Cognito
- More knowledge about other AWS services - Cloudfront, Lambda, Amazon API Gateway
- Infrastructure as Code with Serverless Framework
- Better code management with Git
- Browser and cookie mechanics
- Tradeoffs between serverless vs server based approaches in regards to security, scalability, cost, etc.
Unfortunately this also put even more ideas and projects on my plate:
- Learning Terraform
- Rebuilding all of my existing manual Lambdas and Amazon API Gateways using IaC
- Deploying a Node app using one of the container methods
- How to deploy the same IaC in different clouds like Google Cloud Platform (GCP)