A cloud-native application is a software program that has been developed to be hosted in the cloud. The software program will typically be broken down into multiple services, each running independently, taking advantage of cloud technologies/techniques to ensure these services are resilient, and scale with customer demand. A cloud-native application should also be agile, flexible, and secure.
Traditionally, applications would be monolithic, meaning all the components for the application are integrated together in one solution (tightly coupled) and deployed as one unit. Updating monolithic architecture can be restrictive and time-consuming, harder to scale (it is not possible to scale a small proportion of your application, which can be costly), and can be less flexible and harder to deploy.
The modern approach is often to break down the service into multiple smaller services, each called a microservice. These microservices are independent of each other (loosely coupled) and can be scaled independently, as well as deployed separately. A microservice is an independent service, with its own data store, with the aim of successfully completing one business requirement/task. It’s then possible to orchestrate these independent microservices, to deliver powerful applications.
A resilient application is one that can withstand and recover from events such as hardware failures, network outages, and other unexpected events. There are multiple patterns we can use to provide this resiliency. Depending on the project, you may adopt one or multiple approaches. What follows is a list of some of these patterns (this is not an exhaustive list):
- Bulkhead: Pool elements of an application, so that if one fails the others will continue to function.
- Retry: Enable the application to retry requests to a service or network resource when they fail.
- Circuit breaker: handles faults that may occur when engaging with third-party resources, enabling the application to pause and then retry connection after a variable amount of time.
- Compensating Transaction: this is the ability to undo work undertaken by previous steps when a failure occurs.
- Health endpoint monitoring: expose the health of an application via endpoints that external tools monitor.
When dealing with requests, a service should be able to scale to meet the demand – scaling out/up when demand is high, and scaling in/down when demand is low. This can be easily achieved when using cloud resources, by making configuration changes to the application or cloud resource:
- Scale out: Control the number of concurrent requests a single instance can consume.
- Scale up: Multiplying the number of instances running simultaneously and scaling back down when the demand tails off.
When a team is working on a project, the team should be able to quickly pivot to the project’s demands, following the path to success. Choosing the right platform to plan, track and discuss work, that integrates to your cloud provider seamlessly, providing continuous delivery with observability is required to facilitate a successful project.
Cloud-native applications need to quickly adapt to changes in requirements and in the environment where they are hosted. Taking advantage of new technologies when they become available, and not being locked into any service/technology that slows them down – either in execution, development, or planning.
When designing cloud-native applications, having these isolated independent services can help by reducing the scope of attack. It’s very important to keep security and secure thinking high on the agenda at every stage of a project lifecycle. The following processes and tools can be used to protect your project:
- Threat modelling: Review the threats there are to a system, consider how likely the threats are, and the damage that could occur. Use this knowledge to help guide your focus on higher-priority items.
- Principle of least privilege: the principle is that any user or process should have the smallest number of rights possible to execute its task.
- Penetration testing: Use external actors to attack the system to find security holes to patch.
- Monitoring: Reviewing the logs of services can help spot attacks. Create alerts for known suspicious activity, alerting a team for review when activated.
- Securing the build: The Build server should be secure, and tools should be used to scan for insecure code.
- Building secure code: Choose a secure framework, use secure guidelines to write secure code (OWASP).
- Built-in security: Build in security technologies that actively scan and alert when detecting insecure configurations.