Having shared my experience of implementing microservices in a serverless style in my previous blog, let us iterate the design and learn how to build a serverless website. Since we are iterating and extending the initial architecture design, the focus of this blog will be leveraging existing cloud provider services to build a website.
Let me continue the story that took place in the mystical fairy cloud kingdom, where I was working on a digital transformation program as the Lead Architect. The challenge at hand was different from the phase1, and we knew the benefits of serverless design. The primary driver was still solving the business problem (that is what an architect does, and just not technical solutions- a topic worth a blog in itself). Let us focus on the main functional and non-functional requirements for this phase:
- Build a website for back-office users: Allow back-office users to create, manage, and correct records via a website.
- Maximum re-use of the existing platform: Leverage existing AWS platform and design already built to support serverless backend.
- Role-Based access for users: Granular role-based access control to restrict the functionality features as per the user role.
- Integrated platform: Integration with existing Data services used by Mobile channel.
III. The Test
Addressing requirement 1 turned out the heart of this phase as the choice of technology and stack made vastly fulfilled requirements 2,3 and 4. My previous blog shared our journey with a hybrid mobile application built on the Ionic framework that used Angular under the hoods. So the first logical question we had to answer was which framework to use for the website. Supportability, maintainability, and extensibility were always on the mind. AWS allows static website hosting on S3 (magical serverless moment) without worrying about the fluff of managing any servers. Choosing this option allowed us to stay true to our serverless motto. The pragmatic options at hand were, either use Ionic for building a website or just vanilla Angular. Sticking to Angular would allow us to move developers across the team when needed, and fewer skills to worry about for supporting it later. We did a quick spike with ionic and figured overriding the styling of ionic components was very hacky. We didn’t see any benefits of using another framework on top of Angular. All this created enough doubt for us to go down the safer route to build our website using vanilla Angular. The result was a SPA (Single Page Application) deployed on S3 as a website.
Coming to requirement 3, we also had to ensure that we had some form of role-based access for our back-office users based upon their job functions. It was relatively straight forward. We extended the existing lambda authorizer to allow the new angular application (registered with the IdP as a client application) access to backend endpoints based upon their authorization level determined from the role embedded within the JWT claims.
We did not have to create any new microservice in the backend and were able to use the existing ones. After all, we just added another consumer or channel to our platform. Though we added more features to existing microservices (extension), the effort spent was mostly on the front end. What we had built in the previous phase, we were able to use nearly 100% of it. As the client channels/consumers integrated with the backend microservices, providing access to the same data services and fulfilling requirement 4.
IV. The Build
Let us understand the architectural design and see how the existing solution extended to support our new requirements.
Let me break down the above diagram and explain the design flow from left to right:
- The front-end (SPA) gets loaded on the browser via an HTTP request against the amazon cloud front. Cloud front here serves two purposes, firstly it caches the static content of the website, and secondly, it prevents direct access to the S3 bucket.
- The S3 bucket has the Angular SPA deployed. The S3 policy restricts SPA access to the cloud front only by using the S3 website endpoint as the origin, and access restricted to a custom referer header (secret) set up on the cloud front distribution. It is an important step that many implementations miss or ignore.
- The user of the SPA is required to authenticate himself against the existing IDP (Azure Active Directory) before he/she can request dynamic content from the backend microservices. On successful authentication, the user receives a JWT. The JWT contains an additional/custom claim “role” set up on the IDP(Azure Active Directory)
- From this point onwards, the front end includes the JWT in HTTP request headers for all calls to backend microservices.
- The API Gateway intercepts all calls made to the backend microservices. A lambda authorizer configured with the API gateway performs JWT validation. It checks if JWT hasn’t been tampered with by validating it against the public key provided by the IdP. It additionally looks for the role defined in the JWT claims, if it is allowed access to the requested endpoint. If JWT passed all custom validations, then the authorizer returns an ALLOW policy to API gateway where the response gets cached as per the TTL (time to live) defined. A DENY policy is returned to API gateway in case of failed validation and results in not authorized message response to the front-end.
- API Gateway now invokes the requested backend lambda and successfully serves the front end request.
V. The Results
The new product was designed, built, and successfully delivered in a serverless fashion in no time. So how well did the system measured against the functional and non-functional requirements? Let’s have a look:
Final Reflections and takeaways:
- Use CloudFront for caching/performance, as well as SSL termination.
- Although S3 web hosting requires a bucket to be made publicly accessible, you can and should restrict S3 direct access.
- Turn on access logging on the cloud front. Logging and monitoring is your best friend in a server-less world.
It is a brave new world, and frameworks like Angular, React, Vue makes it more compelling to build and deploy these SPA’s on S3 in a serverless fashion allowing your website to scale effortlessly and cost 70–90% less. Think about it next time when you want to deploy and maintain a web server for a website!! Why would you do that?