Finding the limitations of AWS Amplify
Tags: aws, amplify, cloud, serverless
Published: 2022-01-27 10:23:45

## Preface
This post is based on the experience I had with Amplify@7.6.3 in November 2021. 
When you read this, things might be different...

## AWS Serverless infrastructure
AWS cloud is rich platform, full of servers, elastic searches, databases, and a lot more cloudy stuff. AWS also provides tools to build your application "serverless". That is, write your backend as functionalities and let AWS handle the deployment of it. For example, instead of creating a project for a micro-service and deploying it to a cloud server instance, you just write an AWS Lambda and tell AWS via configurations how it connects to other elements like APIs, databases, or other AWS Lambdas.
AWS takes your Lambda and does all that infrastructure work for you.

There are pros and cons for using a serverless infrastructure at large and AWS specifically. Those relates to your level of control, payment model, and so on. But for now, I'm going to leave all that aside and focus on two AWS tools for building a serverless application

---

## SAM (Serverless Application Model) and Amplify
![Amplify and SAM logos](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sg9hb0czsjkdtd6u3kq5.png)
SAM is one tool AWS provides that allows you to define, via a .yaml file, your backend. What resources you need, how they connect to one another, and so forth.
Amplify is another tool provided by AWS. In fact, it is three tools that work together.

The first tool is the Amplify CLI. The CLI gives you the ability to define your backend, similarly to SAM (since it is sort of a friendlier interface over SAM), but in a command line. You just tell Amplify that you want to create a new Lambda, that it needs access to specific global environment variables, and connect it to your DynamoDB triggers (events that the lambda will be invoked when they occur). Few button clicks, and you're good to go.

Second is the Amplify console. It lets you monitor different deployments, called environments, attach it to your repo and have CI\CD that deploys your backend and frontend when you commit changes to it. It allows you to customize the build process, manage domains, control access and various other options.

The third, is the Amplify library. The library is used in your frontend. It can completely configure your frontend in a couple of lines of code, since Amplify CLI created files that the Amplify library uses to configure everything. You give the library the config file and off you go adding authentication and API calls to your frontend.

## Amplify CLI and GIT
![Amplify environment switching diagram](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1qed6rjh7hfgerjnowkp.jpeg)
Amplify manages the project in the top level as an "Application". Under that, there could be multiple backend environments, and multiple frontends - each deployed from a connected repository branch. You push your changes into your github repo, under the "testing" branch and Amplify will redeploy the front end that is connected to that branch, and update the backend that is connected to that frontend.

The use of multiple environments tries to create a similar way of work as GIT. You can checkout backend environments. Switch between checked out environments. Push (deploy) and pull to your local machine.
You can even create new environments based on the current state of others (i.e. `git checkout -b ...`)
You perform all these actions via the Amplify CLI tool with commands like `amplify env checkout ENV_NAME` or `amplify init`.

---

## "When this baby hits 88 mph, you're gonna see some serious shit"
![Doc and Marty](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bcbrfxvzh03oct2oix73.jpeg)
We've been working on a web application that required fairly straightforward backend: a database, some HTTP methods, authentication, and that's about it. Then, the company had an idea of what direction the product will take and it involved doing a lot of new stuff. We wanted to take a couple of days to see if the idea is technologically viable. We knew that we are going to work fast, encounter a lot of unknowns, and push the boundaries of our knowledge. The hope was that in one week, we'll be able to show the company some serious shit.

## The setup
![Dev team](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nobyj3b8ay5wyxlka6c2.jpeg)
We were a number of developers, split into three different areas of responsibilities.
One team focused on creating a custom authentication flow with AWS Cognito.
The second focused on mostly frontend exploration, with some need for storage and a way to access it.
The third focused on integration with a third party tool that required lambdas that would be triggered by AWS on certain events.

## Where Amplify is powerful
Setting up a new Amplify application, hooking it up to our repo, creating a backend environment, deploying the front end, and connecting it to that backend was a snap. 
Adding an API gateway with a specific path, along with a lambda and dynamoDB was a single command in CLI.
Hats off to AWS, because it was amazingly simple and easy.
It even managed the CI/CD fairly well. When we pushed changed to the repo, it would update the backend and deploy the frontend all on its own.

##Where we struggled with Amplify
We had three teams, so naturally we had four branches: main and one for each team. The way Amplify works with your repo, and allows you to switch environments, is by having files that define the deployment, and those that define the current environment you are working on. For example, the actual code of your lambda is stored. The file `aws-exports.js` that contains information about the active environment is not stored.
Thing is, git and amplify don't actually work together. When you change your branch, the files that are not tracked by git remain the same. You are still on the old environment, but now Amplify sees that your local backend setup is different than what is in the environment.
We tried working the way AWS recommends but it didn't take long until the CLI seemed to go crazy.

![Confusion](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ul13fg203v1f7jvkr3em.jpeg)
I would try to change my environment and it would ask for authentication again, even though I just did. I would pick using access keys and nothing would happen.
If I picked using an AWS profile, it would error out with some error that did not explain itself well.

Because you can deploy your local changes to the cloud without going through the repo, it's easy to collide with others working on the same environment. Naturally, we'd want to have different environments, but when the CLI often went crazy we avoided it and tried to work safely.

##Where Amplify plain does not work
The moment we started working on the custom authentication, we encountered a major boundary of Amplify.
AWS custom authentication requires connecting lambdas to several Cognito triggers. Amplify CLI just does not support it. We had to manually connect everything via the Cognito console.

We had an issue that blocked us for a whole day (which was about 20% of the total time allocated for us). We had a working API Gateway that connected to a lambda, which accessed a DynamoDB table. We needed another one. Created a new path in the API, created a new lambda and DynamoDB, and so on. Everything looked exactly like the existing infrastructure. Only the new stuff didn't work. We would get CORS error all the time. Tried to check the CORS settings, authentication settings, it all seemed ok. Tried to do the process again and again. Tried the create a new API Gateway. Nothing worked...

![Anger from the movie Inside](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jb2pjpnojjopufa1ifd6.jpeg)
Only later one of the developers noticed that the API gateway resource did not update correctly. Only when we created a new environment and the API was reconfigured prior to being deployed, that the issue was finally fixed.

## The last day
As these things go, somehow everything managed to cross the finish line at the very last minute. But we all felt that we succeeded in spite of Amplify.

Part of the team was more familiar with SAM, and by the end of it they said that SAM, while being more complex and leave a lot of the responsibility with the developers, is probably the better tool since it give you the power to configure everything.

## Final thoughts
Amplify is a good tool when your requirements match its capabilities. You could setup a live web page with login capabilities, that stores and loads data via a RESTful API, in literally a few minutes. If you need anything more than that, Amplify is limited and you might find yourself struggling to manage some elements via the AWS console and some via Amplify.

Amplify CLI is a great tool in concept, but we felt it was too unstable and unpredictable. But if you only use a single environment, you won't encounter the most troubling aspects of it.

The Amplify library is pretty good! My only major issue with it is that you have to use Amplify CLI with it or it won't work.

In the end, it's the question of what would you rather have: a big toolbox that allows you to build and control whatever you want, or a pocket knife that is great when you need to cut something but you would have a bad time trying to hammer a nail with it.

![Boyfriend looking at other girl meme](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3l4a9s4g4ewpjoxrse67.jpeg)