Defining a Modern App

Original: https://www.nginx.com/blog/defining-a-modern-app/

Developers, architects, and DevOps engineers are no longer satisfied with the status quo when it comes to designing and building applications. We know this because we talk to them all the time. They’re tired of the challenges in porting applications from one cloud to another. They’ve experienced the intense pressure of spinning up additional compute infrastructure quickly to meet unexpected demand. They’ve struggled to put the right assets in place after suffering a major failure or outage. Basically, they are tired of the stress and hassles of legacy application architectures.

What we’ve heard over and over again from customers and community members is that they want to build “modern apps.” The term is broad enough to mean different things to different people, so we asked our Dev and DevOps colleagues what a modern app means to them. We wanted to create a rock‑solid definition that incorporates all the crucial elements required for modern apps, to act as a checklist and reference point for application development and design efforts going forwards.

This article is in some ways a direct descendant of Thomas Wiggins seminal work, The Twelve Factor App. In fact, almost all of what Wiggins laid out continues to apply today in some form or another. But the application world has evolved to embrace containers, APIs, and truly distributed computing. The Cloud Native Computing Foundation (CNCF) has also laid out a strong high‑level vision for applications, including a supremely useful Trail Map outlining the layers and some architectural considerations for cloud‑native applications including containers, CI/CD, service mesh, observability, and distributed databases.

We wanted to build on these strong foundations and create definitions that developers, architects, and DevOps engineers can benchmark against as they design and deploy applications. We created this definition after discussing application development patterns internally for a number of months and then continuing the discussion with our customers and community members. In our thinking, we divided the definition into two parts – four high‑level concepts and seven principles that support those concepts.

The Four Pillars of Modern Apps (in Eight Flavors)

During our research, we heard over and over again that modern apps must possess crucial attributes which we call the Four Pillars of Modern Apps: scalability, portability, resiliency, and agility. Granted, these terms are buzzwords and commonly used. So, let’s dive in and define what each of these means in the context of designing applications for the modern world of cloud computing and ubiquitous customer connectivity.

Pillar 1: Scalability

There are two elements to scalability: expansion of compute capacity and speed of expansion. They may be inter‑dependent, and both address the same concern. Let’s consider them in the context of “fast scaling” and “long scaling”:

Pillar 2: Portability

In the contemporary “cloud era”, the dream has always been that a DevOps team can simply move an application from one cloud to another and expect it to run perfectly. The reality is quite a bit different. Even with today’s wide use of containers, the differences between clouds – in terms of dependencies, tooling, configuration nuances, and more – make it unrealistic for organizations to expect instant portability as they try to move to a hybrid multi‑cloud architecture. For example, the characteristics of load balancers and data stores on GCP may not directly mirror those on AWS or Azure. Here we lay out a definition of portability that is more realistic and appropriate.

Pillar 3: Resiliency

Resiliency is a generic term that might describe high availability with strict SLAs regarding downtime or more general “reliability” that leaves wiggle room for longer downtimes or time periods when an application is not required to be online, and accepts eventual consistency and service delivery as sufficient. With this in mind, we propose two types of resiliency that every modern app must have to properly serve its purpose.

Pillar 4: Agility

Agility is now a watered‑down buzzword that’s been beaten to death. In the context of modern apps, agility is important in that it describes an aspirational state of moving quickly and decisively with minimal toil and churn. Application dev teams benefit from agility by quickly and easily accessing the resources they need to test and push new features. DevOps teams benefit from agility through simplified and automated checking and deployment of code and infrastructure.

The Seven Principles

To satisfy the Four Pillars of Modern Apps, most modern apps employ architectures following many of these seven principles:

  1. Be platform agnostic – This is related to, but not the same as, portability. Agnosticism means an application is built to run without any consideration of the platforms or environments where it is likely to run.

  2. Prioritize open source software – Open source software (OSS) is rapidly eating the world. Because modern apps require teams to be able to look under the hood of the code in order to design for portability and scalability, using OSS wherever possible is crucial to maintaining the modern apps ethos.

  3. Define everything (possible) by code – Modern apps must move at faster-than-human speed. Automation and programmatic definition of every aspect of modern app requirements and attributes is now table stakes. Granted, no application can be fully automated as yet; humans must remain in the loop for key decisions and to solve anomalous issues. But modern apps can distinguish themselves by steadily and continuously driving more definitions and functionalities into code and away from “tribal knowledge” or runbooks.

  4. Design with automated CI/CD as a native/default state – For the most part, applications are built and then poured over into CI/CD pipelines. Modern apps are designed from the ground up to take into account the eventual requirement of CI/CD automation, for code pushes, infrastructure deployment, and even security requirements.

  5. Practice secure development – Everyone agrees this is important, but few actually do it. It means testing all code as early as possible in the development process using software composition analysis (SCA), static application security testing (SAST), dynamic code analysis (DCA), and formatting checkers. It also means testing any code prior to deployment. CI/CD pipelines must require a “test completed” flag prior to live deployment. For DevOps teams, this also means ensuring that security best practices are followed, such as encrypting internal microservice traffic, not deploying applications unless WAFs are up and running, and automating digital certificate renewals and rotations.

  6. Build with containers – The value of building in containers has become self‑evident. Containers have become the de facto standard for platform‑agnostic runtimes. However, not all dev teams build on containers from the start. To ensure that applications are designed to run in containers, modern apps are built from the start to run in containers.

  7. Widely distribute storage and infrastructure – End users of modern apps today can be anywhere. This doesn’t mean just in terms of at home, working, or out shopping, either – it means anywhere on the globe even or flying above it in a WiFi‑enabled plane! Modern apps must acknowledge this reality and design for a global and distributed delivery and storage capability.

    In addition, modern apps leverage the benefits of distributed computing for greater resiliency, performance, and scaling. Storage that is truly distributed (not just sharded) can dramatically enhance the ability to deliver on the Four Pillars by making sure data is consistent and always available. Infrastructure that is truly distributed – not just in a single geolocation – is also crucial to delivering on the requirements of the Four Pillars. Moving storage and compute closer to customers, wherever they are, can improve performance. Replicating storage and compute across multiple zones or clouds or hybrid deployments can ensure greater resiliency and scalability.

Conclusion: Modern Apps Are Both a Checklist and a State of Mind

Like Schrödinger’s cat, striving towards modern apps means simultaneously existing in two states. There is the real world of the current cloud and hybrid environments, and the time and budgetary constraints under which we develop and deliver applications. And there’s the ideal world of fully automated, highly secure, completely agnostic, instantly scalable, perfect modern apps. The reality is, of course, messy. You may be running a monolithic app that isn’t in containers, can’t double capacity in five minutes, and can’t easily be shifted to other environments without refactoring code. But that doesn’t mean the pillars and principles of modern apps laid out here won’t help you or guide you to a better state. In addition, we anticipate that as the world of technology changes and expands, we’ll have to modify our definition.

Already there are software models that don’t fit neatly into the definition: serverless computing, increasingly sophisticated low‑code/no‑code application platforms and AI‑driven security applications, CDNs with edge‑node compute capacity, and more. That’s why this definition to stretch and grow along with the always‑expanding body of better technology. Just as the The Twelve Factor App still applies today, we hope the definition of a modern app holds up well into the future. In its current state, we hope it can guide your quest to build applications in the best possible way for your users, developers, and all other stakeholders.

Retrieved by Nick Shadrin from nginx.com website.