Book Image

The Definitive Guide to Modernizing Applications on Google Cloud

By : Steve (Satish) Sangapu, Dheeraj Panyam, Jason Marston
Book Image

The Definitive Guide to Modernizing Applications on Google Cloud

By: Steve (Satish) Sangapu, Dheeraj Panyam, Jason Marston

Overview of this book

Legacy applications, which comprise 75–80% of all enterprise applications, often end up being stuck in data centers. Modernizing these applications to make them cloud-native enables them to scale in a cloud environment without taking months or years to start seeing the benefits. This book will help software developers and solutions architects to modernize their applications on Google Cloud and transform them into cloud-native applications. This book helps you to build on your existing knowledge of enterprise application development and takes you on a journey through the six Rs: rehosting, replatforming, rearchitecting, repurchasing, retiring, and retaining. You'll learn how to modernize a legacy enterprise application on Google Cloud and build on existing assets and skills effectively. Taking an iterative and incremental approach to modernization, the book introduces the main services in Google Cloud in an easy-to-understand way that can be applied immediately to an application. By the end of this Google Cloud book, you'll have learned how to modernize a legacy enterprise application by exploring various interim architectures and tooling to develop a cloud-native microservices-based application.
Table of Contents (26 chapters)
1
Section 1: Cloud-Native Application Development and App Modernization in Google Cloud
5
Section 2: Selecting the Right Google Cloud Services
10
Section 3: Rehosting and Replatforming the Application
17
Section 4: Refactoring the Application on Cloud-Native/PaaS and Serverless in Google Cloud

Principles of cloud-native architecture

Cloud-native architecture is the design or approach of building and deploying applications that exist in the cloud to take advantage of the aforementioned cloud delivery models. These models, along with cloud-native architecture, result in scalability, flexibility, and resiliency over their traditional counterparts. Traditional counterparts tend to optimize for a fixed, high-cost infrastructure that requires considerable manual efforts to modify and doesn't allow the immediate scale of additional compute storage, memory, or network resources.

Cloud-native architecture also has five principles that will help you use the cloud-native ecosystem to its fullest while helping you navigate a new development platform. Let's take a look.

Principle 1 – lightweight microservices

Cloud-native architecture is fundamentally a different approach from traditional monolithic applications. Rather than the wholescale development and deployment of applications, cloud-native-architected applications are based on self-contained and independently deployable microservices. Microservices are at the heart of a cloud-native architecture and it is critical for a DevOps-focused pipeline because smaller teams are able to work on small portions of the application.

However, as microservices become more complex and larger, they lose their initial purpose of being agile and modular and become ineffective. Therefore, the first thing to remember when creating microservices is to keep them light and focused. The following are some additional factors to remember when working with microservices:

  • API-based architecture communication: Microservices are completely isolated and packaged into their own portable environments called containers. But they do communicate through APIs, and so a cloud-native architecture uses API-based architecture communication.
  • Independent technology stack: As we mentioned earlier, microservices can be written in different languages and since the microservices are independent of each other, this does not affect anything. So, it's a good idea to use this capability if different members of your development team are proficient in different languages to save time and effort.
  • Independently deployable: Microservices do not need to be deployed at once or one at a time. They can be deployed continuously and concurrently, which is great for mass automated testing. The ideal use of this characteristic is to set up CI/CD pipelines to automate deployment and testing.

Principle 2 – leveraging automation

Cloud-native applications should be architected for automation. Both the architecture and the cloud platform (such as Google Cloud) are extremely automation-friendly, so it is very easy for developers to automate crucial but repetitive tasks involving repairing, scaling, deploying, monitoring, and so on:

  • Infrastructure setup and continual automation: Creating, maintaining, and updating the infrastructure can be automated with tools such as Google Cloud Deployment Manager or Terraform, so if you do not have very specific resource or configuration requirements, automation is the way to go.
  • Development automation: Google Cloud is full of development automation tools that boost productivity and help you focus on improving your app by taking care of more repetitive tasks. One of the most worthwhile investments on your end would be to set up a CI/CD pipeline using tools such as Google Cloud Build, Jenkins, or Spinnaker.
  • Monitoring and auto-heal: Monitoring app performance and health is crucial, especially in the early stages of app development, but it's not feasible to be on the watch 24/7. That's why developers should integrate monitoring and logging systems in their applications right from the start. More importantly, machine learning can be used to analyze data streams in real time for faster decision making.

A cloud-native architecture is built to support automation at every step, so if a process can be automated, consider automating it.

Principle 3 – DevOps culture

The DevOps culture is a philosophy, a development method, and also a principle to abide by when working on a cloud-native project. Adopting DevOps not only boosts agility and your ability to work around problems, but there are also some important things to consider.

For instance, the use of small, independent teams to speed up development is all for nothing if the teams cannot work together. DevOps helps avoid this problem by reducing the friction between teams (especially between development and production teams) by introducing consistency in workflows, collaborative tools, and reducing the burden cross-functional teams traditionally put on each other.

Additionally, companies and teams that have implemented DevOps properly consistently outperform those who haven't. However, implementation isn't all about tools and platforms – it's equally about the people and the mindset. In order to promote the DevOps culture inside your team or company, you must promote innovation and the habit of refining and simplifying your cloud-native architecture.

Principle 4 – better to go managed

Managed services should almost always be chosen over manual operations. Modern managed solutions from cloud platforms are incredibly advanced and can reduce your responsibilities significantly. On top of the saved manpower and time, managed services will often result in cost savings by finding clever ways to reduce operational overhead.

Overall, when feasible, let the cloud do the heavy lifting because the benefits in cost and time savings will almost always outweigh any potential risks of letting the cloud manage things for you.

Principle 5 – innovate

Finally, it's important to always remember that cloud-native applications are very different from traditional application development in one way – they promote experimentation and innovation. First of all, cloud development won't punish developers the same way monoliths do if their experiments go wrong. There are so many protective measures in place that the chance of you damaging your code permanently is close to zero.

More importantly, though, cloud platforms give you the tools to innovate with. Integrate machine learning, conversational tech, IoT, and so much more. If you have a vision, chances are that you'll be able to make it a reality with cloud-native development.

Limitations of microservices

You might be thinking that microservices is the ultimate tool in modern software engineering, better than the monolith in every conceivable way – especially if your experience with microservices is limited or if you've recently learned about the wonders of microservices. However, you'll find that this is not the case.

Like everything else in life, microservices have their own sets of limitations, which means it's not the be-all and end-all that some people might make it out to be. In fact, it won't even be the obvious choice when building a modern application; in certain cases, you still might be better off with a monolith. Furthermore, in order to make the most of microservices, you need to understand the challenges of microservices and know when additional measures need to be undertaken to make up for where it's lacking.

Management of microservices

The value of change is subjective. While most of the changes introduced by microservices are positive in that they help simplify operations for the business, for some businesses, microservices can cause new complications to rise. In essence, the very things that make microservices so useful for modern applications can also make them less functional in certain scenarios – this will also be a theme in all of the limitations that we'll discuss, the first of which is managing microservices.

One of the main objectives behind using microservices is that it adds a degree of modularity, but to achieve that, we need to divide our application into lots of microservices, which, in the case of a growing application, can make mismanagement easier. Although there are additional tools and platforms available for easier microservices management (Google Cloud has one too), the point still stands – don't let your microservices get out of control.

Homogeneity of microservices

The mixed technological stack is a great feature of microservices, but ill-planned or irresponsible usage of this feature could mean that over time, you have microservices with multiple languages, databases, dependencies, and so on within the same project. While this may be convenient during initial application development, technologically complex and inconsistent microservices can become a major inconvenience when teams are switched or when a different developer starts working on a microservice with a language they aren't proficient in. Additionally, you may also have to use different tools to alter microservices within the same project.

Debugging and testing

The testing phase in a microservices architecture is almost always more complex than testing in a monolithic architecture as you are testing tens and hundreds of individual components that may or not be homogeneous in nature (meaning different technologies used).

Furthermore, in addition to testing microservices individually (known as unit tests), developers are also required to test the entire application together (known as integration tests) while taking into consideration interdependencies and APIs. These tests can be automated to a certain degree, but the tests need to be written manually by the developer.

Microservices Death Star

Even though microservices are designed to be isolated and independent of each other, there will be a point in application development (especially in larger projects) where inter-service dependencies are introduced. In fact, this isn't rare at all and there are numerous ways in which dependencies can emerge in an application. As development continues, this can get out of hand and result in an extremely complex architecture that is very interdependent and thus prone to implosion – hence called the microservices Death Star.

However, it's not all bad. As we said, a microservices Death Star is almost always a result of poor management and planning. Similar problems occur in monolithic architectures as well, but microservices provide the benefit of visibility, meaning you can see your architecture becoming interdependent and thus can take steps to control this before it's too late.

DevOps limitations

DevOps and cloud-native applications go hand in hand due to a myriad of reasons, but when paired with microservices, a DevOps implementation can face a few challenges. For instance, microservices development thrives on smaller, independent teams (leading to faster development). However, the large number of teams can make it difficult to unify the goals of the development teams with the operations teams and keep everyone on track – which is one of the main objectives of DevOps.

Fortunately, this can be avoided by planning ahead and making use of the numerous tools at your disposal for DevOps implementation (primarily automation). Remember, at the end of the day, DevOps is here to increase developmental efficiency while reducing time to market and the microservices architecture is an effective way of achieving these goals.

It's true that the microservices architecture won't always be the answer. Despite its limitations, a traditional monolithic application still might make sense in certain cases. For instance, if your application is relatively simple with little to no scope for expansion, the added complexity of the microservices architecture might not be worth it. And overall, regardless of your project, it's important to remember the limitations of microservices to prevent vulnerabilities and administrative headaches in the long run.