Building a Full-Stack AWS Serverless Architecture, Part 1: Frontend Services

Our Grand Rapids Accelerator cohort recently took AWS classes to become certified as Cloud Practitioners. In preparation for the Cloud Practitioner exam, a certified Cloud Practitioner at Atomic simulated a client problem for us to solve. Our “client” wanted a serverless architecture hosted on AWS that would allow them to build mobile and web apps to track packages. We needed to take into consideration many constraints for the system, and we learned several best practices for serverless architectures along the way.

To begin, we brainstormed how the data would move between people and between systems within the architecture. We started from the first interaction a user may have and moved through to the backend components that would need to quickly fulfill their requests and store data. This initial approach helped us discern what types of services we may need. From there, we were able to come up with a list of services that we might use to solve the problems. We then narrowed that list based on any constraints of each feature.

In this two-part series, we’ll dive into the services that we decided to use, with considerations for architecting a full-stack AWS serverless application; for our first part, we’ll explore considerations for the services that the frontend would use.



Users’ first interaction in the application is logging in, so we needed a service that would provide us with secure identity authentication. Although there are other identity services available outside of AWS, Cognito is the primary client-facing service that AWS provides.

Cognito is an identity service that allows us to authenticate our users. In the context of our client problem, Cognito’s access control fulfilled a requirement that only certain features would be accessible to a subset of users. Cognito also supports social and enterprise identity providers, which would allow our users to sign in using identity services like Google, Facebook, etc.

Since our client already used Google for authentication, we could easily integrate authentication with their existing accounts. Given the time constraints of our client, it was a bonus that Cognito is also straightforward to integrate into several different mobile and web frameworks with only a few lines of code!

Routing & Domain Mapping


Once a user signs in, they need a way to access the rest of the application. CloudFront is Amazon’s content delivery network (CDN) service, which securely delivers applications or data. Combined with Route 53 (see below), using CloudFront distributions would provide routing to other areas of our infrastructure for anything our users interact with. This allows us to configure domain mapping for our application. You can think of CloudFront as the starting point for how everything else in the application is handled.

One of our colleagues recommended using a CloudFront distribution in front of the S3 bucket that we were planning to use for storing our application assets (see below). This distribution would allow us to configure access, security, caching, and other settings for our web and mobile content.

Route 53

Route 53 is a Domain Name System (DNS) service that provides a way to route user requests, configure custom domain mappings to CloudFront distributions, and manage custom domain names and routes (ex: Used in conjunction with CloudFront, this service would allow us to handle DNS for a custom domain for the web and mobile assets in our application, as well as the API. Plus, unlike other DNS services, Route 53 provides “health checks.” That means if your application is down or network issues arise, it will redirect users to an appropriate resource while the problem is being fixed. The added protection Route 53 provides is another bonus for our client.

Global Accelerator

If you’re anticipating a lot of traffic and want some fine-grain control over the performance of your application, consider using AWS’ Global Accelerator service. The Global Accelerator service aids with routing and networking in ways that optimize traffic flow. The service is particularly useful if you anticipate there will be a lot of traffic and you need to deploy your infrastructure to multiple regions and want to easily route traffic between these global regions.

Since our client anticipated a high volume of international traffic, the additional benefits of adding the Global Accelerator service to the architecture outweighed additional monetary costs. Depending on how you intend to use Global Accelerator, you may need to also use and configure a Virtual Private Cloud.

Application Interface Storage


Amazon’s Simple Storage Service (S3) provides a way to store any number of resources (“objects”) in storage “buckets.” This maximizes security, reliability, and availability of those resources. For our situation, we could use an S3 bucket to store our web application assets, and another for our mobile application assets. Alternately, we could have one bucket for both, but since there would be more traffic to the single bucket, choosing to do this could decrease the speed of the system. While there are many types of S3 buckets to choose from, depending on an organization’s resource availability and pricing needs, the best bucket for our use case would be the standard bucket, the ideal choice for frequently accessed resources.

It can be overwhelming to determine which of the many available services to use, especially when working with specific constraints, like a completely serverless system. While the above services are viable options for serverless architecture, each has tradeoffs. Check out our next part on considerations for the backend and database services, and let us know if there are any services or portions of the system that you would approach differently!