This is what I found:

1 — Design for Culture

Cloud-native is purely technical but the human side is important. There’s a link between your teams' structure and culture and what they produce as a result. This is what Melvin Conway coined:

Organizations which design systems … are constrained to produce designs which are copies of the communication structures of these organizations.

2 — Design for Composability

Build microservices and decompose your monolith into simple, lightweight, loosely coupled services that can be developed and released independently of each other.

3 — Design for Automation

“I think the automation of vision is a much bigger deal than the invention of perspective.” ~ Trevor Paglen

Automation has always been one of the good practices when building infrastructures and online platforms. Automating cloud-native systems include:

Infrastructure using tools like Terraform, Ansible, and Saltstack

CI and CD using tools like Jenkins

System recovery and scalability

Make sure to simplify and secure before automation.

4 — Design for Statelessness

Stateless services are “smarter” than stateful services. They allow these features to be implemented easily:

Scaling up/down

Gracefull termination for replacement (repairing)

Rollback tasks

Load balancing

One may ask about the state of a service using a session persistence between the client and the server in a stateless service.

Well, in a stateless design, there is no state between client requests. Every client request will have sufficient info to perform the requested action.

5 — Design for Dev/Prod Parity

As it’s described in The 12 Factor App: Keep development, staging, and production as similar as possible. Dev/Prod parity makes processes like CI and CD easy.

6 — Design for Isolation

Cloud-native applications are designed in a way to run without having affinities with the server and the operating system.

7 — Design for Reactiveness

As it’s described in the Reactive Manifesto, reactive systems are responsive which means they should absolutely have two features: elasticity and resilience. This is implemented using message-driven applications (e.g: streaming logs).

Reactive Systems rely on asynchronous message-passing to establish a boundary between components that ensures loose coupling, isolation and location transparency

8 — Design for Interaction and Collaboration (API-centered applications)

Cloud-native services communicate using lightweight APIs that are based on protocols like REST, NATs or gRPC.

9 — Design for Abstraction (Everything as a Service)

Develop, and deploy your services using highly automated platforms that provide a service abstraction. Abstraction and automation are highly related.

The example of abstracting the data and separating it from the computing layer and the business logic layer allows automation and makes operations on data like data caching easier and more performant.

10 — Design for Business

DevOps is about aligning teams around common business goals, but this will not happen unless you design accordingly. So create business capability teams and deploy business services.

11 — Design for Immutability

Developers used to continually SSH into servers to continually update the deployed artifacts, from a cloud-native perspective this is an artisanal/handicraft way of doing things.

Immutability in this context is replacing the old version of an application by building new servers from an artifact and totally replacing the old one.

12 — Design for Observability

Design observable applications that can interface with observability tools and give insights (metrics, logs, traces ..etc) into what your code does in production (or any other environment).

Making the difference between noise and signals when designing for observability make things easier.

13 — Design for Security

Or develop with security in mind and secure by design. Security is not an afterthought.

14 — Design for Simplicity

Simple can be harder than complex but keep in mind that in order to build complex systems that work, you need to build it from simple subsystems that work.

Unix philosophy originated by Ken Thompson can be an inspiration to build complex systems like Linux while keeping in mind a philosophy of minimalism:

Write programs that do one thing and do it well.

Write programs to work together.

Write programs to handle text streams, because that is a universal interface.

15 — Design like Nature

Nature has 13 billion years of experience in research and development on her CV.

The dinosaurs, weighty and slow creatures have disappeared and left the earth for smaller, more agile and more intelligent species.

This is how software engineering is evolving: Monolith applications are giving the place to distributed systems composed of lighter and more sophisticated systems.

Don’t think that monolith will totally disappear, they will continue to support the IT ecosystem for years. The fact that more sophisticated approaches were invented, doesn’t mean a total instantaneous disappearance of other approaches.

When a whale dies, it supports a community of organisms and provides life for hundreds of marine animals for more than 50 years.

The other thing that nature can inspire us is the “afterward optimization” approach. Remember: Dinosaurs evolved into birds.

I am not an expert in this area, but during the transmission of DNA information, mutations can happen and in some cases, they can give birth to new phenotypes that are more sophisticated and evolved.

This is how nature works, things are never optimized from the beginning, they are post-optimized.

Richard P. Gabriel suggests that a key advantage of Unix was that it embodied a design philosophy he termed “worse is better”, in which simplicity of both the interface and the implementation are more important than any other attributes of the system — including correctness, consistency, and completeness. Gabriel argues that this design style has key evolutionary advantages.. (wikipedia)

Practically in the case of cloud-native, you can, for example, adopt the Monolith First approach.

Experts recommend taking the same approach by building a monolith application at the beginning, even if your intention is to create a microservices architecture.

This will help you in understating the domain and the business boundaries of your application first to make decomposing the application easier and avoid disrupting the organization.

Microservices and cloud-native are to monolith what birds are to dinosaurs, if you can’t start with since you can evolve into.

Similar Stories

If you liked this story, you will like other stories I wrote about similar topics:

Connect Deeper

Make sure to follow me on Medium / Twitter to receive my future articles. You can also check my online training Painless Docker and Practical AWS.

U nlike most stories on Medium is free and not behind a paywall. If you liked this work, you can support it by buying me a coffee here.

Follow us on Twitter 🐦 and Facebook 👥 and join our Facebook Group 💬.

To join our community Slack 🗣️ and read our weekly Faun topics 🗞️, click here⬇