[Developer's community]

Design your app for the cloud (best practices)

I had no opportunity to write in recent days. In this topic, I decided to share something unusual and highly theoretical. I want to talk about the best practices for adapting apps for the cloud (Microsoft Azure, particularly, but most of them are applicable to any cloud provider). I hope that the concepts outlined below will help you to understand the process better, and hence, apply it in practice when necessary.

Many organizations are thinking of migrating to the cloud. If we follow the famous Gartners’ strategies, the options are the following:

  • Rehost
  • Refactor
  • Replatform

and you might also hear of (as an alternative for legacy systems):

  • Retire
  • Retain
  • Repurchase

These are also known as six R’s of migration strategies. Let’s consider them briefly one by one:

Rehost (also known as ‘lift-and-shift’) is all about the applications hosted on-premises, and the most common approach for the cloud migration is to move the existing workloads ‘as-is’ to the cloud. That being said, the (bare metal) servers are moved to Azure Virtual Machines, the network infrastructure is recreated with VNet’s (Azure virtual networks) and protected by a firewall at the VNet level and NSG (Network Security Groups) if we’re talking about the subnets, etc. Customers benefited from the PAYG model (pay-as-you-go) and managed infrastructure that provides more flexibility and scalability options.

Replatform is similar to the ‘rehost’ strategy. It means retaining the core Architecture and benefiting from the managed services in Azure (such as database services, ML, Data analytics, Storage, etc.).

Refactoring can be treated as a total application overhaul, i.e., reviewing how the application was Architected and adapting it for the cloud (utilizing cloud-native features). A good example of this strategy could be splitting the monolithic app into layers or expressing certain parts of the app as microservices, or using completely different database technology, like NoSQL, instead of relational DB, etc.

Retire. Well, first of all, why is it here, you may ask? This strategy is rather related to cost optimization (reviewing and shutting down not used/redundant/deprecated applications).

Retain. This strategy is all about revisiting the on-prem apps and leaving them be at the local datacenter (due to the high cost of migration, impossibility to migrate, strategic objectives, other business, and technical concerns).

Repurchase. This one makes sense if you’re moving toward a SaaS solution (software-as-a-service). A good example: migrating your CRM system to Salesforce (cloud-hosted).

You may have seen other strategies, like Rebuild or Re-Architect, but these are essentially the subsets of ‘refactoring’ that may assume a different level of effort (i.e., a light upgrade or a total app overhaul). The basic strategies can be best represented by the following diagram:

 

What if you’re designing the application for the cloud from scratch or Re-Architecting an existing one? In this case, to get the most out of Azure, you need to follow the best practices outlined below.

There are a couple of design principles (best practices) you need to keep in mind if you go down this road:

  1. Design for self-healing
  • Avoid single points of failure (SPOF)
  • Design for transient fault handling (intermittent network failures, etc.)intermittent network failures, etc.
  • Failover (if the primary instance can’t be reached, failover to secondary one)
  • Separate the monolith into several layers (and hence, cloud services or apps)
  • Degrade gracefully (i.e., provide reduced functionality, but keep the most critical services online)
  • Use paired Azure regions for high-availability (HA) scenarios
  1. Build with security in mind
  • Encrypt data at rest (storage encryption) and in transit (TLS)
  • Enforce and cultivate the least privilege principle
  • Use Firewalls and DDoS protection at the Virtual Network level and Network Security Groups for subnets
  • Use advanced security measures and tools like Security Center and Azure Sentinel
  1. Implement elasticity
  • Identify and mitigate the bottlenecks
  • Implement auto-scaling for Virtual Machines (scale sets) and Kubernetes clusters (scalability rules)
  • Do not forget about scale-in operations
  • Architect for resiliency: leverage self-healing capabilities available in App Servies and implement similar logic
  • Utilize managed services to gain more flexibility in the cloud
  1. Leverage a wide variety of storage options
  • Use CDNs (available by default in Azure Storage accounts) to make the data available at the edge locations (data centers closest to end-users)
  • Use zone-redundant (ZRS) storage option to copy data synchronously across three different availability zones or geo-zone-redundant option (GZRS) that copies data to a distinct geographic region
  • Store sessions and static data in Azure Cache for Redis for the best user experience and performance
  1. Practice loose coupling between the main components of the system
  • Use Storage Queues or Azure Service Bus (for more sophisticated tasks)
  • Leverage managed services, like mailing service (SendGrid) or notification service (Azure Notification Hub)
  1. Parallelize where possible
  • Use Load Balancers, Traffic Managers, Azure Front Door services to support parallel processing, availability, and resiliency
  • Scale horizontally (add more compute instances), not vertically (by adding more horsepower to the same machine)
  • Rightsize your workloads
  1. Take care of operations
  • Ensure that the system remains healthy by using Azure Monitor and configuring alerts
  • Track the availability and performance of the system by collecting and analyzing logs in Azure LogAnalytics
  • Track the operations important for auditing and regulatory purposes
  1. Design for evolution

This is probably one of the most valuable items…

  • Abstract away the infrastructure from the domain logic
  • Use asynchronous messaging
  • Enforce high cohesion and loose coupling (as mentioned above)
  • Deploy the moving parts of the system independently (widely spread approach in Microservice Architectures but also applicable elsewhere)

 

As an ending word, I’d like to share the link to a resource that can help you in this endeavor: Azure Architecture Center. In that portal, you’ll be able to find useful design patterns, the Architecture samples, and lots of other valuable information.

Add comment

Loading