Cloud-native applications are small, independent, and loosely coupled (micro) services, designed to deliver some business value. The goal is to deliver businesses what they want at the pace they want. Cloud-native applications are typically developed as micro-services packaged in containers and managed by platforms such as Kubernetes. The cloud-native applications are designed to provide a consistent experience across the private, public, or hybrid cloud platforms. Automation, self-service, on-demand resource provisioning are some of the additional advantages of cloud computing.
Cloud-native App Development
Twelve-Factor App methodology (https://12factor.net) provides guidelines for building SaaS applications. They are designed to provide applications with scalability, resilience, continuous delivery, portability etc. Here I am explaining the concepts in the context of .net core system.
Codebase : Every app should have its own codebase in version control. Do not share codebase across multiple applications. The recommended way of sharing functionality is through nuget packages from a repository/artifactory.
Configuration: Should be separated from code. Configuration refers to anything that changes across environments. Examples are DB connection strings, hostname, port, credentials to any service provides like AWS etc. This principle addresses 2 concerns: Security, Portability and Traceability. The configuration should be stored preferably in a version control system, with proper security access permissions. A micro-services will read the configuration from the config service and any change to an environment config file will get deployed to the respective environment automatically.
Dependencies : Should be explicitly declared, isolated, and injected. Eg for . .net core, all dependencies can be individually declared in a manifest (package.config) as NuGet packages.
Backing Services: Backing service is any service your service is dependent on and should be connected through external Urls to avoid tight coupling.
Build, Release, Run: Strictly separate the build, release, and run stages. During the Build stage, the artifacts are crated from the source code and pushed to the artifact repository. During Deploy stage, the artifacts are combined with an external configuration specific to the respective environment to which it has to be deployed. In the Run stage, the application is started in the target environment.
Stateless Processes: Application processes should run in a stateless mode. For example, sticky sessions, local file system storage or in-memory cache will make the system stateful and violate this principle. Instead of local Cache, one should use an external caching mechanism like Redis. It is one of the core SOA principles for scalability.
Port Binding: Expose services through port-binding. Each application instance (or container) should be reachable via a unique port. This along with statelessness makes the containers scalable.
Concurrency/Scalability: Scale the application horizontally adding more copies.
Disposability: Applications should be quick to start and graceful to shutdown. Your application should have application lifetime events configured accordingly to handle these events gracefully. .Net core 2.2 supports IApplicationLifetime to support lifetime events. And your deployment environment should support starting another instance/container immediately. It also might point to a need for resilience support at the client-side by having some service like Polly.
Dev-Prod Parity: Keep both the environments as much similar as possible. It helps to re-produce an issue easily. The idea is not to share the prod environment settings with Dev, but to have the similar application set up in both environments.
Logs: For cloud-native applications, logging shouldn’t be done as to file within a container as the containers can get unstable and cal lead of loss of logs. Even logging as a backing service to the containers is not recommended as this can cause contention in the logging system. The recommended approach is to do logging as an Event stream and hence can be tapped and managed outside the system independently. The logs can then be analyzed using tools like ELK (Elastic Search, Log Stash, Kibana) OR Splunk.
Admin Tasks: The one-off admin tasks should be insolated and have an independent development, packaging, and execution. Examples include database migrations, running one time scripts for functional use cases etc.
These provide a very though guidelines for any micro-service development framework and should be taken care of according to the development platform you have chosen.