Alcobuddy: A Story based Approach to Understanding Cloud Native Applications
By: Dunith Dhanushka
Tags: Microservices, Continuous Delivery, Agile Development, Cloud Native Apps, DevOps

The making of Alcobuddy

Having a good IT background under his belt, Shenal analyzed the whole project’s scope and came up with the initial architecture.

Alcobuddy Solution Architecture

The solution comprises of a mobile app (obviously!) and a Java-based backend. The mobile app will communicate with the backend over REST APIs exposed by the backend app.

Shenal is a little rusty on mobile app development and Java development knowledge. So he hired two developers for the mobile app and the backend to work remotely. With the seed capital received from Dexter, Shenal bought a new server to host the backend and transformed his garage into a mini data center. He’ll be playing the operations guy role going forward.

So everyone teamed up with big dreams in their minds, rolled their sleeves up and started hacking.

The big bang release

The initial release took more time than they expected. They thought of rolling out the first cut of the app within one month. But things didn’t work out that way. Here’s why.

Mobile app developer and the backend developer were located in two different timezones.

Mobile app developer often depended on the backend developer for APIs. The communication gap limited their time for collaborative development and testing. Integration testing was a nightmare!

Integration testing was a nightmare! The backend developer suddenly left the startup at the verge of their first release. So Shenal hired a new developer and he had to go through the entire codebase to learn everything from scratch .

. Provisioning the infrastructure took a lot of time and effort. Shenal had to assemble the server part by part, supply electricity and cooling, Internet connections, and finally install the whole stack of software and third-party libraries to get the backend application up and running.

After spending 6 months in the development and testing, they finally launched the app to the market.

But a local ride-hailing company stole their idea and launched it as a feature to their already existing app just one month before Alcobuddy.

Alcobuddy was late to the market…

The production days

Despite being late to the market, Alcobuddy started getting some traction. There was a sizable market had been consuming the app.

Bugs: Nobody is perfect

We know nothing is perfect at first. So does Alcobuddy. One day, a lot of users complained that they couldn’t log into the app. Shenal had to call the mobile developer and then they did some diagnosis. Apparently, the backend database had crashed and none of the users were able to log in.

Shenal had to coordinate with two developers and debug the code for the app and the backend. Finally, they found a bug in the backend code that leaked the database connection. Fixing this bug took both developers a lot of time as they had to depend on each other (plus the time zones didn't help either). Also, they had to run the full integration test suite again, build the app, package it and finally deploy to production. During this window of time, u Alcobuddy users experienced a critical downtime and they took to the Alcobuddy FB page to vent it out. Ouch!!!

Responding to business needs

In the meantime, Alcobuddy’s investor, Dexter was having plans to do a concert with his band. So he wanted to offer a discount to any Alcobuddy user that requests a chauffeur to and from the concert. Dexter wanted to get this feature rolled out ASAP. So he communicated that to Shenal via Ivan.

This means that Shenal had to roll out a new feature into production since the current version of the app doesn’t support offering discounts. Both the mobile app and backend has to be changed and the timelines were not helping out since they only had 2 days left to roll out the feature. Shenal was like “Ohh, not again!”

Once again, Shenal rolled his sleeves up and sat down with the two developers. But it took more time than they thought. The backend developer had to apply major changes into almost all the API methods. Those changes were followed by the changes in value objects, service implementation and finally in the database schema. The mobile developer had to change app UI to meet the need. When both developers are done, Shenal had to run the tests, build the package and deploy.

Shenal’s team had spent sleepless nights and finally, when they were ready, the concert was over.

Dexter was not happy…

Business is booming — time to scale

Despite the constant hiccups, it went through, Alcobuddy’s business was booming. Prices of booze were reduced so that people started crawling into pubs and called Alcobuddy to rescue them ;)

Ivan was happy, but definitely, Shenal was not. He spent most of the time in the garage taking care of outages and crashes. The backend had almost reached its max capacity. Shenal wanted to bring in a new server to balance the load and increase the availability. Shenal had to experience the agony of infrastructure provisioning again.

After the upgrade, Shenal’s workload increased. Now he has two servers in his fleet which requires duplicate efforts on configuring, applying patches, taking backups and monitoring.

Shenal was not so happy…

Operational costs and revenue

Ivan noticed that the operational cost of the business went through the roof, proportionate to the demand. He was expecting a fat margin from the increased demand. But apparently, Shenal’s IT expenses ate into that.

Since Alcobuddy was used by the users who are active at night time, the app hardly received traffic in the day time. Both servers were idling during the day time. But they had to be constantly powered up and bandwidth had to be allocated. This lead to unnecessary operational cost and business was not making enough money to run its operations.

So everyone was not happy with the current situation.

What really went wrong with Alcobuddy?

Now let’s do an analysis of the past events at Alcobuddy.

It took a long time to roll out the first production release which leads to increased the time to market — This was due to the dependency between two teams, lack of coordination due to decentralized nature and the initial time taken to provision infrastructure.

— This was due to the dependency between two teams, lack of coordination due to decentralized nature and the initial time taken to provision infrastructure. Developer experience was not the best — Both developers depended on each other to develop and test the code. In order to do a release, developers and operations need a lot of coordination and effort.

— Both developers depended on each other to develop and test the code. In order to do a release, developers and operations need a lot of coordination and effort. Lack of business agility — Shenal’s team failed to deliver the new feature before Dexter’s concert due to the friction in the delivery process and failure to respond to new business needs, pointing at the lack of agility.

— Shenal’s team failed to deliver the new feature before Dexter’s concert due to the friction in the delivery process and failure to respond to new business needs, pointing at the lack of agility. Scaling the business needed a lot of effort — Scaling the infrastructure had created additional workloads on the operations side. Responding to scaling needs took a long time.

— Scaling the infrastructure had created additional workloads on the operations side. Responding to scaling needs took a long time. Ever increasing operational costs — Business had to spend more money on the servers which are not utilized during the day time. They were paying for idling resources.

The Alcobuddy team got together and did some soul searching to figure out a way to fix the current situation.

Embracing the change: Going Cloud Native

Cloud Native Applications are the new kid in the block these days. Everybody seems religiously adopting that. But what has motivated them to go Cloud Native? Let’s find out.

Before we dive into the details, let’s look at the definition of Cloud Native Applications. I’d like to quote Pivotal here.

What are Cloud Native Applications?

Cloud-native is an approach to building and running applications that exploits the advantages of the cloud computing delivery model. Cloud-native is about how applications are created and deployed, not where. — Pivotal

According to the above, Cloud Native applications reap the benefits of deploying them on cloud infrastructure. But what about the “cloud” in cloud-native applications?

If an app is “cloud-native,” it’s specifically designed to provide a consistent development and automated management experience across private, public, and hybrid clouds. — RedHat

By combining these two definitions, we can simply say that Cloud Native Application development is the practice of building applications without thinking about where they might get deployed. Cloud Native applications abstract away the infrastructure requirements for applications, allowing them to be deployed and migrated across multiple environments in a consistent manner. Those environments could be private, public, or hybrid clouds.

This allows application developers to focus more on their business problems rather than addressing infrastructure and logistical concerns.

In the next section, let’s learn why you should adopt the Cloud Native application methodologies with the lessons learned by Alcobuddy team.

Alcobuddy: The Cloud Native Days

After having a few rounds of discussions, the Alcobuddy team was convinced they need to move to the cloud. But they were not so confident that moving to the cloud would solve all of their existing problems. Also, they had no clue or guidance on how to initiate the Cloud Native journey.

Then Shenal stepped outside from his comfort zone and acted as a true CTO there. He mastered the principals of Cloud Native Application development and determined to instill a culture inside Alocobuddy to utilize the Cloud Native concepts for their day to day operations.

Along with Shenals guidance, Alcobuddy team took some radical approaches to restructure the way they used to deliver the applications to the market which were based on the key tenets of Cloud Native Application development as follows.

Courtesy of Pivotal

Let’s look at those approaches in detail.

Adopting the Microservices architecture

Microservices architecture decomposes applications into small, loosely coupled independently operating services.

Along with his developers, Shenal took a lead on breaking up their monolithic Java-based backend application into a collection of Microservices with a bounded context. These services map to smaller, independent development teams and make possible frequent, independent updates, scaling, and failover/restart without impacting other services.

— Since Microservices are independently developed and communicated over standard interfaces, backend developer was able to develop and test his code in isolation without depending on the app developer. So the tight coupling between two developers was taken away.

— Hiring new backend developers and get them to up to the speed was easier and scalable. Earlier, the new developer had to go through the entire code base to get familiarise with the business domain. But now a developer has to own and know only a defined domain of knowledge and code.

Containers as the deployment vehicle for Microservices

Individual Microservices are packaged in containers. Containers offer a lower resource utilization, fast startup time, low distribution size and above all it abstracts away the underlying deployment platform complexities from the developer. Instead of configuring, patching, and maintaining operating systems, now developers focus on their application context.

— Since containers are portable across environments, developers were able to quickly troubleshoot the production issues in their local workstations without replicating the production environment. This has drastically reduced the time to attend critical bugs.

— Developers were able to verify fixes and features across multiple environments in a shorter cycle time. This has drastically cut down the time to needed to verify fixes.

Moving the application infrastructure to the cloud

Shenal took a radical decision to go with a container orchestration engine service offered by a cloud vendor. He selected a managed Kubernetes service so that he no longer had to spend time in front of hardware boxes, configuring them, installing software, patching and constantly monitoring them for outages.

— Operations were offloaded to the cloud vendor so that Shenal could focus more on his core business rather than tending the server farm in his garage.

— The operational risks were mitigated to the cloud vendor. High availability, monitoring, and disaster recovery will be handled by the cloud vendor.

— Cloud infrastructure offered an outstanding on-demand scale-out and scale-in facility. Most of the scaling scenarios were fully automated so that ops team no longer needed to manually provision/decommission compute units. That helped Alcobuddy to respond to varying demand much faster while providing a consistent user experience.

— With the cloud vendor’s Pay-As-You-Go scheme, Alcobuddy was able to cut down many infrastructure expenses. They were charged only for what they had consumed. Alcobuddy finally moved from CAPEX to OPEX which let them invest the saved expenses back into the business.

Establishment of a DevOps culture and a Continuous Delivery (CD) pipeline

If done right, DevOps culture lays out a foundation for building, testing and releasing software rapidly, frequently, and more consistently.

Continuous Delivery makes it possible to continuously adapt software in line with user feedback, shifts in the market and changes to business strategy. Test, support, development, and operations work together as one delivery team to automate and streamline the build-test-release process.

After establishing solid DevOps practice and a CD process, software releases were no longer a painful or risky job. Shenal teamed up with the developers and implemented a fully cloud-based CI/CD pipeline that automates everything from building containers, run test suites on lower environments to finally deploy them on production in a reliable manner.

Reference architecture of a CI/CD pipeline implemented at Google Cloud Platform (GCP)

— Alcobuddy drastically cut down the time taken to ship new features and bug fixes to the users with this new practice. That eventually increased the release velocity and allowed them to respond to the shifts in the market in a more faster and reliable manner.

And They Delivered Happily Ever After…

After embracing the Cloud Native movement in a meaningful way, Alcobuddy took off the ground fast, became agile, lean and mean. They streamlined their value delivery pipeline by making the right technology choice at the right time.

If you are in doubt of going Cloud Native, I suggest you consider the benefits that Alcobuddy enjoyed once they embraced going Cloud Native.

— Breaking the Java-based monolithic backend application into a collection of Microservices lead the development team to gain a better developer experience, reduced coupling among team members, and apply robust programming according to the Twelve-Factor App. — DevOps culture and CI/CD process automated all manual and cumbersome tasks. This has reduced the time to move fixes and new features into production more frequently with less risk. Ultimately that helped them to respond to ever-changing business needs much faster. — Containerising of application code abstracted away from the infrastructure concerns. That made the application components more portable across different environments and made the debugging easy. — Moving to a cloud-based container orchestration platform reduced its operational costs. Also, they benefitted from the inherent on-demand scalability and reliability features offered by the cloud vendor. Moreover, the risk of owning their infrastructure has been successfully mitigated.

As a parting note, I’d like to extend my gratitude to my colleague Shenal Mendis for coming up with those awesome avatars for the characters.