# Migrating a Legacy App to Cloud Native — Part 1

Photo by [Aryan Singh](https://unsplash.com/@wuzclicks?utm_source=medium&utm_medium=referral) on [Unsplash](https://unsplash.com?utm_source=medium&utm_medium=referral)

Over the course of eight months I made a journey. You might say that my application made a journey, but it was a journey for me as well to learn and struggle my way through some new development tools. Along the way, I documented that journey to share with you. This post is part one of eight to share that journey. Throughout, I try to be fair and honest; respectful both to the authors of these tools and services and to you my readers…

In this post, I begin exploring how to migrate my [SqAC](https://sqac.fanello.net) app to be an AWS cloud native application. I give some background about the current app architecture, consider lift & shift and serverless approaches to migration, before declaring my intended approach. The next part in the series will present and discuss the new architecture.

### Background

*(Bear with me, or just skim through to the next section.)*

In 2015, I began learning to become a square dance caller. 🎤🕺🏻 Square dancing is a fun hobby and social outing, and I was ready for a new challenge. As I learned the mechanics of calling a dance though, I was constantly thinking “I can write an app to help with this.” 🤔

As a software engineer by day, I found that my career was moving from writing Java backend applications, to writing full-stack web applications. There were some gaps in my knowledge to make this leap.

Thus in 2016 a fusion of purposes was born. I would write that niche app for square dance callers, and I would use it to expand my programming experience into new areas. 🎉 It would be far more interesting than yet another to-do app 😴, as so many others have written when they want to play with new technology.

I started playing the [Dart 1.0](https://dart.dev/), which seemed really cool yet also really immature. I tried [Ionic 2](https://ionicframework.com/), but ran into usability troubles; a framework *on top of* another framework was complex and documentation was poor at the time. So I went a layer down to the underlying framework, [Angular 2](https://angular.io/). [Material Design](https://material.io/) existed, but the Angular library for it was still being built and missing critical components, and so I chose [Bootstrap 3](https://getbootstrap.com/docs/3.3/) which was still popular at the time.

The application needed a simple backend to authenticate users, save their data, and allow for optional sharing. My early prototype was written in Dart, but ultimately I decided to use [Typescript](https://www.typescriptlang.org/) for the backend to pair with the Angular front-end. A bit of exploring brought me to [Feathers](https://feathersjs.com/), a framework that combines the [Express.js](https://expressjs.com/) web server with [Passport](http://www.passportjs.org/) for user authentication. I threw it up on a [DigitalOcean droplet](https://www.digitalocean.com/products/droplets/) server, which is basically a tiny virtual machine instance with a persistent file system.

I want to provide a pretty diagram showing the existing architecture… but this is all there is:

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1650409306679/MLiWTpM-N.png)

Also, since this is a server there’s also a README file explaining how to configure the server, including:

*   Auto-run the custom Feathers server. (Remember, it’s Express.js.)
*   Setting up Nginx with SSL to proxy to the Feathers server,
*   Cron job to rotate the [Let’s Encrypt](https://letsencrypt.org/) SSL certificate.
*   Cron job to backup the user data to an S3 bucket; the one piece of AWS.

This is *not* Infrastructure as Code (IaC)! Rather, this is the kind of setup where one dreads ever needing to rebuild. At least I had the foresight to document the manual process. 🤷‍♂️ At the time, that was something.

After two years, the app reached feature completion, and I learned a whole lot about front-end development *and* square dance choreography during the journey. Occasionally, other people even use it!

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1650409307727/PSFbPRd2R.png)

Around the same time as that completion, I became a certified [AWS Solutions Architect](https://aws.amazon.com/certification/certified-solutions-architect-associate/). I’m still using Angular for web apps, but the backend… the cloud… oh my! I can do so much better now.

And so the stage is set. I have an existing application and want to move it to AWS. This is the classic cloud migration, albeit at a small scale. What are my options?

### Lift & Shift

The most straight-forward approach is to setup an [AWS Lightsail](https://aws.amazon.com/lightsail/) instance running Ubuntu, follow my README instructions to setup a new server. Copy the data, redirect DNS, and I’m done. ✅

**Advantage**: Quick and easy.  
**Disadvantage**: I accomplished absolutely nothing!

If I take this approach, I spent a day of my time so that I can pay a few dollars a month to Amazon instead of a few dollars a month to DigitalOcean. There’s been no gain. ¯\\_(ツ)\_/¯

What else can I do to take *advantage* of AWS?

*   Move the user data to S3 or DynamoDB? Yes, then I can use EC2 instead of Lightsail.
*   Move the web app files to S3 and serve it with CloudFront? Yes indeed!
*   Run the Express.js app in a Lambda? Now we’re getting interesting, and fitting into free tier!
*   Switch authentication over to Cognito? Oh yes!

When we start thinking like this, we leave the realm of Lift & Shift and head into…

### Cloud Native

Cloud native development is when an application is *architected* to work natively in the cloud, taking advantage of managed services. Cloud native is not exactly the same as serverless, but the two often go hand in hand; an ideal cloud native architecture often is serverless, requiring none of that server setup work in my old README file.

### Not Merely Serverless

The ideas thrown out above would achieve serverless. Using Cognito, Lambda, S3, DynamoDB, and CloudFront would make for a serverless solution. I could do this very easily, as I have done many times before. It’d be easy, and *I would learn nothing* in the process. Moving my app to AWS this way would take more time than a simple lift & shift and it would save me around $5/month (vs DigitalOcean) because my usage would fall under the free tier for all those AWS services. I thought about this for about a year, but the time spent isn’t worth saving so little money and I wouldn’t *learn* anything.

There’s something newer hitting mainstream development though. I’m even giving a presentation about it next month for the local AWS User Group, and yet I haven’t done anything of *substance* with this newer technology stack yet. And so once again, three years after the last time, a fusion of purpose has been born. I will migrate my app with…

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1650409308869/857tohRYV.png)

### Coming next time….

I will explore my app’s requirements, and architect a solution using AWS Amplify.

