It's all about how you develop and deploy application instead of where you are deploying application be it public cloud or private data center. Application designed in this way can best make use of offering provided by cloud. First step in that direction is building micro-service based applications and run them in containerized and orchestrated platform like Kubernetes.
Following are the design principals one should consider while creating Cloud applications.
Applications are created as micro-service so one can make use of best language, frameworks and tools suitable for different applications. Let's say we can build real-time applications using Nodejs, REST applications using Spring-Boot or Dropwizard and ML applications using python.
Containerized application requires less resources then VMs and starts up in fraction of seconds. Containers packages applications into small, lightweight execution environment which shares host operating system. Containers helps isolating different micro services running in same host operating system. Docker has been used heavily for containerization.
Containerized application applications can be deployed using orchestration platform like Kubernetes which helps in container management, application deployment, scaling which has become standard for cloud application deployment.
Consider resources as disposable as opposed to traditional way of thinking of physical fixed servers in data center where application used to be running.
Consider resources as immutable infrastructure where once application is deployed, it never gets updated instead new resources are provisioned for each deployment which can greatly improves consistency of application deployment/rollback.
There are many service offered by cloud which can be used by applications so instead of investing resources in setting up that infrastructure in managing it, one can leverage managed services offered by different cloud providers.
Scared of vendor lock in ?
It's trade off operation cost of managing it or using managed services. You can always use many open source managed services offered by cloud and for others you have to decide based on operational costs.
Scalability is the ability to scale application without changing design and it achieved by scaling up and down whenever required. Scalability leads to other principals like Stateless applications and Disposable resources.
Elasticity is the ability to use resource dynamically and all cloud providers offer it as pay as you go model. It solves problem of over-provisioning of resources for applications deployed in traditional data center.
Stateless applications maintain states outside of application in database or other external entity so nodes can be added dynamically and removed and deployed applications without worrying about state. Application components also should be stateless as stateless components can be easily scaled, repaired, rolled-back and load balanced. Scalability can be achieved easily by designing stateless applications.
Loosely Coupled architecture reduces inter dependency between application components so one failed component does not impact whole application.
- Services registers themselves and discovered automatically by other services
- Service endpoints does not need to be hard coded in applications.
- Decoupled components does not interact each other directly
- Communication between components happen using various message brokers like ActiveMq, SQS, etc..
Application is fault tolerant means it should continue functioning in-spite of fault detected in one of the application component. While Resiliency is about ability to recover from failures to the operation state when it was before failure so it's all about responding to failures without any downtime and data loss.
Resiliency should be at core of any architecture and you should practice it from start when designing any application.
Resilient applications offers High availability and Disaster recovery using load balanced clusters, multi-region deployments, replication, continuous monitoring.
Different ways to make application resilient:
- Load balancing to avoid single point of failure
- Retry intermittent failures
- Circuit breaker to avoid cascading failures
- Request throttling to avoid unavailability and DDOS attacks
- Distributed transaction rollback using SAGA pattern
Application component should communicate with each other using well defined authentication method without thinking whether it's internal service or external service to avoid any security vulnerability
Last but very very important is we should strive for automation in every part of application development, build, deployment, monitoring, etc ...
Infrastructure automation can be achieved by provisioning infrastructure using tools like Terraform, Serverless, Cloudformation etc..
CI/CD pipeline greatly reduces manual efforts and help in automating everything from build, test, package and deployment. There are various tools like Jenkins, Spinnaker, Code pipeline, etc...
Automating scale up helps application availability during peak load and scale down reduces cost when application are not used heavily. Sometimes you can scale down to 0 for internal applications which are used rarely to further reduce costs.
Centralized logging and monitoring greatly helps in maintaining services in healthy condition and it should be automated using different tooling so if issue can be detected quickly and fixed.
Automated backup solution in place so data can be recovered quickly without much loss of data.